Add QGoogleDriveFolderPicker

This commit is contained in:
2022-09-23 10:35:24 -05:00
parent 734c2b4ea0
commit 01916286b0
5 changed files with 158 additions and 21 deletions

View File

@ -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.17", "@kingsrook/qqq-frontend-core": "1.0.20",
"@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,7 @@
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-flatpickr": "3.10.7", "react-flatpickr": "3.10.7",
"react-github-btn": "1.2.1", "react-github-btn": "1.2.1",
"react-google-drive-picker": "^1.2.0",
"react-html-parser": "2.0.2", "react-html-parser": "2.0.2",
"react-images-viewer": "1.7.1", "react-images-viewer": "1.7.1",
"react-quill": "1.3.5", "react-quill": "1.3.5",

View File

@ -84,8 +84,8 @@ function ProcessLinkCard({
</MDTypography> </MDTypography>
{ {
isReport isReport
? `Click here to run the process called ${title}.` ? `Click here to access the ${title} report.`
: `Click here to access the ${title} report.` : `Click here to run the process called ${title}.`
} }
{percentage.label} {percentage.label}
</MDTypography> </MDTypography>

View File

@ -87,6 +87,11 @@ function QDynamicForm(props: Props): JSX.Element
values[fieldName] = ""; values[fieldName] = "";
} }
if (field.omitFromQDynamicForm)
{
return null;
}
if (field.type === "file") if (field.type === "file")
{ {
return ( return (
@ -95,7 +100,7 @@ function QDynamicForm(props: Props): JSX.Element
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<Button variant="outlined" component="label"> <Button variant="outlined" component="label">
<span style={{color: "#606060"}}>Choose file to upload</span> <span style={{color: colors.lightBlue[500]}}>Choose file to upload</span>
<input <input
id={fieldName} id={fieldName}
name={fieldName} name={fieldName}

View File

@ -0,0 +1,110 @@
/*
* 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/>.
*/
import {colors} from "@mui/material"
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid";
import {useFormikContext} from "formik";
import React, {useEffect, useState} from "react";
import useDrivePicker from "react-google-drive-picker";
import MDBox from "qqq/components/Temporary/MDBox";
export function QGoogleDriveFolderPicker(): JSX.Element
{
const clientId = process.env.REACT_APP_GOOGLE_APP_CLIENT_ID;
const appApiKey = process.env.REACT_APP_GOOGLE_APP_API_KEY;
const [ selectedGoogleFolderName, setSelectedGoogleFolderName ] = useState(null as string);
const [ selectedGoogleFolderId, setSelectedGoogleFolderId ] = useState(null as string);
const [ googleToken, setGoogleToken ] = useState(null as string); // maybe get from cookie/local-storage
const [ openPicker, authResponse ] = useDrivePicker();
const formikProps = useFormikContext();
const handleOpenPicker = (token: string) =>
{
openPicker({
clientId: clientId,
developerKey: appApiKey,
viewId: "FOLDERS",
token: token, // pass oauth token in case you already have one
showUploadView: false,
showUploadFolders: false,
supportDrives: true,
multiselect: false,
setSelectFolderEnabled: true,
setIncludeFolders: true,
callbackFunction: (data) =>
{
if (data.action === "cancel")
{
console.log("User clicked cancel/close button");
setSelectedGoogleFolderId(null);
setSelectedGoogleFolderName(null);
}
else
{
console.log(data);
setSelectedGoogleFolderId(data.docs[0].id);
setSelectedGoogleFolderName(data.docs[0].name);
}
},
});
};
if(authResponse && authResponse.access_token && authResponse.access_token !== googleToken)
{
setGoogleToken(authResponse.access_token);
}
useEffect(() =>
{
formikProps.setFieldValue("googleDriveAccessToken", authResponse?.access_token);
formikProps.setFieldValue("googleDriveFolderId", selectedGoogleFolderId);
formikProps.setFieldValue("googleDriveFolderName", selectedGoogleFolderName);
}, [selectedGoogleFolderId, selectedGoogleFolderName])
return (
<Grid item xs={12} sm={6}>
<MDBox mb={1.5}>
<Box display="flex" alignItems="center">
<Button variant="outlined" onClick={() => handleOpenPicker(googleToken)}>
<span style={{color: colors.lightBlue[500]}}>Select Google Drive Folder</span>
</Button>
<Box ml={1} fontSize={"1rem"}>
{selectedGoogleFolderName}
</Box>
</Box>
{/*
<MDBox mt={0.75}>
<MDTypography component="div" variant="caption" color="error" fontWeight="regular">
{errors[fieldName] && <span>You must select a file to proceed</span>}
</MDTypography>
</MDBox>
*/}
</MDBox>
</Grid>
);
}

View File

@ -54,6 +54,7 @@ import MDBox from "qqq/components/Temporary/MDBox";
import MDButton from "qqq/components/Temporary/MDButton"; import MDButton from "qqq/components/Temporary/MDButton";
import MDProgress from "qqq/components/Temporary/MDProgress"; import MDProgress from "qqq/components/Temporary/MDProgress";
import MDTypography from "qqq/components/Temporary/MDTypography"; import MDTypography from "qqq/components/Temporary/MDTypography";
import {QGoogleDriveFolderPicker} from "qqq/pages/process-run/components/QGoogleDriveFolderPicker";
import QValidationReview from "qqq/pages/process-run/components/QValidationReview"; import QValidationReview from "qqq/pages/process-run/components/QValidationReview";
import QClient from "qqq/utils/QClient"; import QClient from "qqq/utils/QClient";
import QValueUtils from "qqq/utils/QValueUtils"; import QValueUtils from "qqq/utils/QValueUtils";
@ -393,6 +394,11 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
<QProcessSummaryResults qInstance={qInstance} process={processMetaData} table={tableMetaData} processValues={processValues} step={step} /> <QProcessSummaryResults qInstance={qInstance} process={processMetaData} table={tableMetaData} processValues={processValues} step={step} />
) )
} }
{
component.type === QComponentType.GOOGLE_DRIVE_SELECT_FOLDER && (
<QGoogleDriveFolderPicker />
)
}
{ {
component.type === QComponentType.RECORD_LIST && step.recordListFields && recordConfig.columns && ( component.type === QComponentType.RECORD_LIST && step.recordListFields && recordConfig.columns && (
<div> <div>
@ -510,6 +516,7 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
if (newIndex === null) if (newIndex === null)
{ {
setProcessError(`Unknown process step ${newStep}.`); setProcessError(`Unknown process step ${newStep}.`);
return;
} }
setActiveStepIndex(newIndex); setActiveStepIndex(newIndex);
setOverrideOnLastStep(null); setOverrideOnLastStep(null);
@ -520,15 +527,20 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
setActiveStep(activeStep); setActiveStep(activeStep);
setFormId(activeStep.name); setFormId(activeStep.name);
let dynamicFormFields: any = {};
let formValidations: any = {};
let initialValues: any = {};
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// if this step has form fields, set up the form // // if this step has form fields, set up the form //
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
if (activeStep.formFields || processValues.inputFieldList) if (activeStep.formFields || processValues.inputFieldList)
{ {
let fullFieldList = getFullFieldList(activeStep, processValues); let fullFieldList = getFullFieldList(activeStep, processValues);
const {dynamicFormFields, formValidations} = DynamicFormUtils.getFormData(fullFieldList); const formData = DynamicFormUtils.getFormData(fullFieldList);
dynamicFormFields = formData.dynamicFormFields;
formValidations = formData.formValidations;
const initialValues: any = {};
fullFieldList.forEach((field) => fullFieldList.forEach((field) =>
{ {
initialValues[field.name] = processValues[field.name]; initialValues[field.name] = processValues[field.name];
@ -548,27 +560,36 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
}); });
setDisabledBulkEditFields(newDisabledBulkEditFields); setDisabledBulkEditFields(newDisabledBulkEditFields);
} }
setFormFields(dynamicFormFields);
setInitialValues(initialValues);
setValidationScheme(Yup.object().shape(formValidations));
setValidationFunction(null);
} }
else if (doesStepHaveComponent(activeStep, QComponentType.VALIDATION_REVIEW_SCREEN))
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// define an inner function here, for adding more fields to the form, if any components have form fields built into them //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const addField = (fieldName: string, dynamicFormValue: any, initialValue: any, validation: any) =>
{ {
//////////////////////////////////////// dynamicFormFields[fieldName] = dynamicFormValue;
// this component requires this field // initialValues[fieldName] = initialValue;
//////////////////////////////////////// formValidations[fieldName] = validation;
const dynamicFormFields: any = {}; }
dynamicFormFields.doFullValidation = {type: "radio"};
const initialValues: any = {}; if (doesStepHaveComponent(activeStep, QComponentType.VALIDATION_REVIEW_SCREEN))
initialValues.doFullValidation = "true"; {
addField("doFullValidation", {type: "radio"}, "true", null);
setOverrideOnLastStep(false); setOverrideOnLastStep(false);
}
const formValidations: any = {}; if (doesStepHaveComponent(activeStep, QComponentType.GOOGLE_DRIVE_SELECT_FOLDER))
formValidations.doFullValidation = null; {
addField("googleDriveAccessToken", {type: "hidden", omitFromQDynamicForm: true}, null, null);
addField("googleDriveFolderId", {type: "hidden", omitFromQDynamicForm: true}, null, null);
addField("googleDriveFolderName", {type: "hidden", omitFromQDynamicForm: true}, null, null);
}
if(Object.keys(dynamicFormFields).length > 0)
{
///////////////////////////////////////////
// if there are form fields, set them up //
///////////////////////////////////////////
setFormFields(dynamicFormFields); setFormFields(dynamicFormFields);
setInitialValues(initialValues); setInitialValues(initialValues);
setValidationScheme(Yup.object().shape(formValidations)); setValidationScheme(Yup.object().shape(formValidations));