diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py index 55c958977..224791108 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py @@ -40,7 +40,8 @@ def setup_database_configs(app: Flask) -> None: if pool_size is not None: pool_size = int(pool_size) else: - # this one doesn't come from app config and isn't documented in default.py because we don't want to give people the impression + # this one doesn't come from app config and isn't documented in default.py + # because we don't want to give people the impression # that setting it in flask python configs will work. on the contrary, it's used by a bash # script that starts the backend, so it can only be set in the environment. threads_per_worker_config = os.environ.get("SPIFFWORKFLOW_BACKEND_THREADS_PER_WORKER") @@ -50,8 +51,9 @@ def setup_database_configs(app: Flask) -> None: # this is a sqlalchemy default, if we don't have any better ideas pool_size = 5 - app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {} - app.config['SQLALCHEMY_ENGINE_OPTIONS']['pool_size'] = pool_size + app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {} + app.config["SQLALCHEMY_ENGINE_OPTIONS"]["pool_size"] = pool_size + def load_config_file(app: Flask, env_config_module: str) -> None: """Load_config_file.""" diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index a74aa829b..5a422e5fa 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -94,6 +94,9 @@ export default function TaskShow() { const params = useParams(); const navigate = useNavigate(); const [disabled, setDisabled] = useState(false); + const [noValidate, setNoValidate] = useState(false); + + const [taskData, setTaskData] = useState(null); const { addError, removeError } = useAPIError(); @@ -108,6 +111,7 @@ export default function TaskShow() { useEffect(() => { const processResult = (result: Task) => { setTask(result); + setTaskData(result.data); setDisabled(false); if (!result.can_complete) { navigateToInterstitial(result); @@ -160,22 +164,30 @@ export default function TaskShow() { } }; - const handleFormSubmit = (formObject: any, event: any) => { + const handleFormSubmit = (formObject: any, _event: any) => { if (disabled) { return; } + const dataToSubmit = formObject?.formData; if (!dataToSubmit) { navigate(`/tasks`); return; } let queryParams = ''; - if (event && event.submitter.id === 'close-button') { + + // if validations are turned off then save as draft + if (noValidate) { queryParams = '?save_as_draft=true'; } setDisabled(true); removeError(); delete dataToSubmit.isManualTask; + + // NOTE: rjsf sets blanks values to undefined and JSON.stringify removes keys with undefined values + // so there is no way to clear out a field that previously had a value. + // To resolve this, we could potentially go through the object that we are posting (either in here or in + // HttpService) and translate all undefined values to null. HttpService.makeCallToBackend({ path: `/tasks/${params.process_instance_id}/${params.task_id}${queryParams}`, successCallback: processSubmitResult, @@ -290,17 +302,27 @@ export default function TaskShow() { return errors; }; + // This turns off validations and then dispatches the click event after + // waiting a second to give the state time to update. + // This is to allow saving the form without validations causing issues. + const handleSaveAndCloseButton = () => { + setNoValidate(true); + setTimeout(() => { + (document.getElementById('our-very-own-form') as any).dispatchEvent( + new Event('submit', { cancelable: true, bubbles: true }) + ); + }, 1000); + }; + const formElement = () => { if (!task) { return null; } let formUiSchema; - let taskData = task.data; let jsonSchema = task.form_schema; let reactFragmentToHideSubmitButton = null; if (task.typename === 'ManualTask') { - taskData = {}; jsonSchema = { type: 'object', required: [], @@ -341,7 +363,7 @@ export default function TaskShow() { closeButton = (