mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Merge branch 'dev' into feature/QQQ-38-app-home-widgets
This commit is contained in:
@ -13,7 +13,7 @@
|
|||||||
"@fullcalendar/interaction": "5.10.0",
|
"@fullcalendar/interaction": "5.10.0",
|
||||||
"@fullcalendar/react": "5.10.0",
|
"@fullcalendar/react": "5.10.0",
|
||||||
"@fullcalendar/timegrid": "5.10.0",
|
"@fullcalendar/timegrid": "5.10.0",
|
||||||
"@kingsrook/qqq-frontend-core": "1.0.10",
|
"@kingsrook/qqq-frontend-core": "1.0.12",
|
||||||
"@mui/icons-material": "5.4.1",
|
"@mui/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.4.1",
|
"@mui/material": "5.4.1",
|
||||||
"@mui/styled-engine": "5.4.1",
|
"@mui/styled-engine": "5.4.1",
|
||||||
|
@ -45,6 +45,9 @@ import QClient from "qqq/utils/QClient";
|
|||||||
import QValueUtils from "qqq/utils/QValueUtils";
|
import QValueUtils from "qqq/utils/QValueUtils";
|
||||||
import Footer from "../../components/Footer";
|
import Footer from "../../components/Footer";
|
||||||
import QProcessUtils from "../../utils/QProcessUtils";
|
import QProcessUtils from "../../utils/QProcessUtils";
|
||||||
|
import {QActionsMenuButton, QCreateNewButton} from "qqq/components/QButtons";
|
||||||
|
import QValueUtils from "qqq/utils/QValueUtils";
|
||||||
|
import LinearProgress from "@mui/material/LinearProgress";
|
||||||
import "./styles.css";
|
import "./styles.css";
|
||||||
|
|
||||||
const COLUMN_VISIBILITY_LOCAL_STORAGE_KEY_ROOT = "qqq.columnVisibility";
|
const COLUMN_VISIBILITY_LOCAL_STORAGE_KEY_ROOT = "qqq.columnVisibility";
|
||||||
@ -657,15 +660,11 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
The
|
The
|
||||||
<strong>{` ${selectedIds.length.toLocaleString()} `}</strong>
|
<strong>{` ${selectedIds.length.toLocaleString()} `}</strong>
|
||||||
records on this page are selected.
|
records on this page are selected.
|
||||||
<button
|
<Button onClick={() => setSelectFullFilterState("filter")}>
|
||||||
type="button"
|
|
||||||
onClick={() => setSelectFullFilterState("filter")}
|
|
||||||
className="MuiButton-root MuiButton-text MuiButton-textPrimary MuiButton-sizeSmall MuiButton-textSizeSmall MuiButtonBase-root css-knwngq-MuiButtonBase-root-MuiButton-root"
|
|
||||||
>
|
|
||||||
Select all
|
Select all
|
||||||
{` ${totalRecords.toLocaleString()} `}
|
{` ${totalRecords.toLocaleString()} `}
|
||||||
records matching this query
|
records matching this query
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -675,15 +674,11 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
All
|
All
|
||||||
<strong>{` ${totalRecords.toLocaleString()} `}</strong>
|
<strong>{` ${totalRecords.toLocaleString()} `}</strong>
|
||||||
records matching this query are selected.
|
records matching this query are selected.
|
||||||
<button
|
<Button onClick={() => setSelectFullFilterState("checked")}>
|
||||||
type="button"
|
|
||||||
onClick={() => setSelectFullFilterState("checked")}
|
|
||||||
className="MuiButton-root MuiButton-text MuiButton-textPrimary MuiButton-sizeSmall MuiButton-textSizeSmall MuiButtonBase-root css-knwngq-MuiButtonBase-root-MuiButton-root"
|
|
||||||
>
|
|
||||||
Select the
|
Select the
|
||||||
{` ${selectedIds.length.toLocaleString()} `}
|
{` ${selectedIds.length.toLocaleString()} `}
|
||||||
records on this page
|
records on this page
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* QQQ - Low-code Application Framework for Engineers.
|
|
||||||
* Copyright (C) 2021-2022. 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.selectionTool
|
|
||||||
{
|
|
||||||
margin-left: 40px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {QComponentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QComponentType";
|
import {QComponentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QComponentType";
|
||||||
|
import {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException";
|
||||||
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
||||||
import {QFrontendComponent} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendComponent";
|
import {QFrontendComponent} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendComponent";
|
||||||
import {QFrontendStepMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
import {QFrontendStepMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
||||||
@ -53,6 +54,10 @@ interface Props
|
|||||||
process?: QProcessMetaData;
|
process?: QProcessMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const INITIAL_RETRY_MILLIS = 1_500;
|
||||||
|
const RETRY_MAX_MILLIS = 12_000;
|
||||||
|
const BACKOFF_AMOUNT = 1.5;
|
||||||
|
|
||||||
function ProcessRun({process}: Props): JSX.Element
|
function ProcessRun({process}: Props): JSX.Element
|
||||||
{
|
{
|
||||||
const processNameParam = useParams().processName;
|
const processNameParam = useParams().processName;
|
||||||
@ -62,6 +67,7 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
// process state //
|
// process state //
|
||||||
///////////////////
|
///////////////////
|
||||||
const [processUUID, setProcessUUID] = useState(null as string);
|
const [processUUID, setProcessUUID] = useState(null as string);
|
||||||
|
const [retryMillis, setRetryMillis] = useState(INITIAL_RETRY_MILLIS);
|
||||||
const [jobUUID, setJobUUID] = useState(null as string);
|
const [jobUUID, setJobUUID] = useState(null as string);
|
||||||
const [qJobRunning, setQJobRunning] = useState(null as QJobRunning);
|
const [qJobRunning, setQJobRunning] = useState(null as QJobRunning);
|
||||||
const [qJobRunningDate, setQJobRunningDate] = useState(null as Date);
|
const [qJobRunningDate, setQJobRunningDate] = useState(null as Date);
|
||||||
@ -343,8 +349,6 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(`Steps are: ${steps}`);
|
|
||||||
// console.log(`Setting step to ${newStep}`);
|
|
||||||
let newIndex = null;
|
let newIndex = null;
|
||||||
if (typeof newStep === "number")
|
if (typeof newStep === "number")
|
||||||
{
|
{
|
||||||
@ -446,9 +450,6 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
if (activeStep && activeStep.formFields)
|
if (activeStep && activeStep.formFields)
|
||||||
{
|
{
|
||||||
console.log("In useEffect for disabledBulkEditFields");
|
|
||||||
console.log(disabledBulkEditFields);
|
|
||||||
|
|
||||||
const newDynamicFormFields: any = {};
|
const newDynamicFormFields: any = {};
|
||||||
const newFormValidations: any = {};
|
const newFormValidations: any = {};
|
||||||
activeStep.formFields.forEach((field) =>
|
activeStep.formFields.forEach((field) =>
|
||||||
@ -519,22 +520,21 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
if (lastProcessResponse)
|
if (lastProcessResponse)
|
||||||
{
|
{
|
||||||
setLastProcessResponse(null);
|
setLastProcessResponse(null);
|
||||||
|
setRetryMillis(INITIAL_RETRY_MILLIS);
|
||||||
|
|
||||||
setQJobRunning(null);
|
setQJobRunning(null);
|
||||||
|
|
||||||
if (lastProcessResponse instanceof QJobComplete)
|
if (lastProcessResponse instanceof QJobComplete)
|
||||||
{
|
{
|
||||||
const qJobComplete = lastProcessResponse as QJobComplete;
|
const qJobComplete = lastProcessResponse as QJobComplete;
|
||||||
console.log("Setting new step.");
|
|
||||||
setJobUUID(null);
|
setJobUUID(null);
|
||||||
setNewStep(qJobComplete.nextStep);
|
setNewStep(qJobComplete.nextStep);
|
||||||
setProcessValues(qJobComplete.values);
|
setProcessValues(qJobComplete.values);
|
||||||
// console.log(`Updated process values: ${JSON.stringify(qJobComplete.values)}`);
|
|
||||||
}
|
}
|
||||||
else if (lastProcessResponse instanceof QJobStarted)
|
else if (lastProcessResponse instanceof QJobStarted)
|
||||||
{
|
{
|
||||||
const qJobStarted = lastProcessResponse as QJobStarted;
|
const qJobStarted = lastProcessResponse as QJobStarted;
|
||||||
setJobUUID(qJobStarted.jobUUID);
|
setJobUUID(qJobStarted.jobUUID);
|
||||||
console.log("setting need to check because started");
|
|
||||||
setNeedToCheckJobStatus(true);
|
setNeedToCheckJobStatus(true);
|
||||||
}
|
}
|
||||||
else if (lastProcessResponse instanceof QJobRunning)
|
else if (lastProcessResponse instanceof QJobRunning)
|
||||||
@ -542,7 +542,6 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
const qJobRunning = lastProcessResponse as QJobRunning;
|
const qJobRunning = lastProcessResponse as QJobRunning;
|
||||||
setQJobRunning(qJobRunning);
|
setQJobRunning(qJobRunning);
|
||||||
setQJobRunningDate(new Date());
|
setQJobRunningDate(new Date());
|
||||||
console.log("setting need to check because running");
|
|
||||||
setNeedToCheckJobStatus(true);
|
setNeedToCheckJobStatus(true);
|
||||||
}
|
}
|
||||||
else if (lastProcessResponse instanceof QJobError)
|
else if (lastProcessResponse instanceof QJobError)
|
||||||
@ -560,28 +559,50 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
console.log("In effect for checking status");
|
|
||||||
if (needToCheckJobStatus)
|
if (needToCheckJobStatus)
|
||||||
{
|
{
|
||||||
console.log(" and the bool was true");
|
|
||||||
setNeedToCheckJobStatus(false);
|
setNeedToCheckJobStatus(false);
|
||||||
if (jobUUID)
|
(async () =>
|
||||||
{
|
{
|
||||||
(async () =>
|
setTimeout(async () =>
|
||||||
{
|
{
|
||||||
setTimeout(async () =>
|
try
|
||||||
{
|
{
|
||||||
|
console.log("OK");
|
||||||
const processResponse = await QClient.getInstance().processJobStatus(
|
const processResponse = await QClient.getInstance().processJobStatus(
|
||||||
processName,
|
processName,
|
||||||
processUUID,
|
processUUID,
|
||||||
jobUUID,
|
jobUUID,
|
||||||
);
|
);
|
||||||
setLastProcessResponse(processResponse);
|
setLastProcessResponse(processResponse);
|
||||||
}, 1500);
|
}
|
||||||
})();
|
catch (e)
|
||||||
}
|
{
|
||||||
|
if (e instanceof QException)
|
||||||
|
{
|
||||||
|
const qException = e as QException;
|
||||||
|
const status = Number(qException.status);
|
||||||
|
if (status !== undefined && !Number.isNaN(status) && status >= 500 && status <= 600)
|
||||||
|
{
|
||||||
|
if (retryMillis < RETRY_MAX_MILLIS)
|
||||||
|
{
|
||||||
|
console.log(`500 error, attempting to retry in ${retryMillis + retryMillis} millis`);
|
||||||
|
setRetryMillis(retryMillis * BACKOFF_AMOUNT);
|
||||||
|
setNeedToCheckJobStatus(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Retry millis [${retryMillis}] is greater or equal to the max retry limit [${RETRY_MAX_MILLIS}], giving up...`);
|
||||||
|
setProcessError("Could not connect to server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
}, retryMillis);
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
}, [needToCheckJobStatus]);
|
}, [needToCheckJobStatus, retryMillis]);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// do the initial load of data for the process - that is, meta data, plus the init step //
|
// do the initial load of data for the process - that is, meta data, plus the init step //
|
||||||
@ -611,8 +632,6 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
// queryStringForInit = `recordsParam=filterId&filterId=${urlSearchParams.get("filterId")}`
|
// queryStringForInit = `recordsParam=filterId&filterId=${urlSearchParams.get("filterId")}`
|
||||||
// }
|
// }
|
||||||
|
|
||||||
console.log(`@dk: Query String for init: ${queryStringForInit}`);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const processMetaData = await QClient.getInstance().loadProcessMetaData(processName);
|
const processMetaData = await QClient.getInstance().loadProcessMetaData(processName);
|
||||||
@ -687,7 +706,6 @@ function ProcessRun({process}: Props): JSX.Element
|
|||||||
|
|
||||||
setTimeout(async () =>
|
setTimeout(async () =>
|
||||||
{
|
{
|
||||||
console.log("Calling processStep...");
|
|
||||||
const processResponse = await QClient.getInstance().processStep(
|
const processResponse = await QClient.getInstance().processStep(
|
||||||
processName,
|
processName,
|
||||||
processUUID,
|
processUUID,
|
||||||
|
@ -103,4 +103,10 @@
|
|||||||
.MuiInputAdornment-sizeMedium *
|
.MuiInputAdornment-sizeMedium *
|
||||||
{
|
{
|
||||||
font-size: .875rem !important;
|
font-size: .875rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.MuiDataGrid-toolbarContainer .selectionTool
|
||||||
|
{
|
||||||
|
margin-left: 40px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
@ -34,11 +34,7 @@ class QClient
|
|||||||
private static handleException(exception: QException)
|
private static handleException(exception: QException)
|
||||||
{
|
{
|
||||||
console.log(`Caught Exception: ${JSON.stringify(exception)}`);
|
console.log(`Caught Exception: ${JSON.stringify(exception)}`);
|
||||||
const {logout} = useAuth0();
|
throw (exception);
|
||||||
if (exception.status === "401")
|
|
||||||
{
|
|
||||||
logout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getInstance()
|
public static getInstance()
|
||||||
|
Reference in New Issue
Block a user