/*
* 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 .
*/
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
import {colors} from "@mui/material";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid";
import {useGoogleLogin} from "@react-oauth/google";
import {useFormikContext} from "formik";
import React, {useEffect, useState} from "react";
import useDrivePicker from "react-google-drive-picker";
import MDTypography from "qqq/components/legacy/MDTypography";
interface Props
{
showDefaultFoldersView: boolean;
showSharedDrivesView: boolean;
qInstance: QInstance;
}
export function GoogleDriveFolderPicker({showDefaultFoldersView, showSharedDrivesView, qInstance}: Props): JSX.Element
{
const clientId = qInstance.environmentValues.get("GOOGLE_APP_CLIENT_ID") || process.env.REACT_APP_GOOGLE_APP_CLIENT_ID;
const appApiKey = qInstance.environmentValues.get("GOOGLE_APP_API_KEY") || process.env.REACT_APP_GOOGLE_APP_API_KEY;
if(!clientId)
{
console.error("Missing environmentValue GOOGLE_APP_CLIENT_ID")
}
if(!appApiKey)
{
console.error("Missing environmentValue 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 [ errorMessage, setErrorMessage ] = useState(null as string);
const [ openPicker, authResponse ] = useDrivePicker();
const formikProps = useFormikContext();
const loginOrOpenPicker = (token: string) =>
{
if(token)
{
handleOpenPicker(token);
}
else
{
login();
}
};
const driveScope = "https://www.googleapis.com/auth/drive"
const login = useGoogleLogin({
scope: driveScope,
onSuccess: tokenResponse =>
{
console.log("Token response");
console.log(tokenResponse);
if(tokenResponse.scope.indexOf(driveScope) == -1)
{
setErrorMessage("You must allow access to Google Drive after you sign in. Please try again.")
return;
}
else
{
setErrorMessage(null)
}
setGoogleToken(tokenResponse.access_token)
handleOpenPicker(tokenResponse.access_token);
}
});
const handleOpenPicker = (token: string) =>
{
// @ts-ignore
const google = window.google
const customViewsArray: any[] = [];
if(showDefaultFoldersView)
{
customViewsArray.push(new google.picker.DocsView(google.picker.ViewId.FOLDERS)
.setIncludeFolders(true)
.setMode(google.picker.DocsViewMode.LIST)
.setSelectFolderEnabled(true));
}
if(showSharedDrivesView)
{
customViewsArray.push(new google.picker.DocsView(google.picker.ViewId.FOLDERS)
.setEnableDrives(true)
.setIncludeFolders(true)
.setMode(google.picker.DocsViewMode.LIST)
.setSelectFolderEnabled(true));
}
openPicker({
clientId: clientId,
developerKey: appApiKey,
viewId: "FOLDERS",
token: token, // pass oauth token in case you already have one
disableDefaultView: (customViewsArray.length > 0), // if we have any custom views, then disable the default.
showUploadView: false,
showUploadFolders: false,
supportDrives: true,
multiselect: false,
setSelectFolderEnabled: true,
setIncludeFolders: true,
customViews: customViewsArray,
callbackFunction: (data) =>
{
if (data.action === "cancel")
{
console.log("User clicked cancel/close button");
setSelectedGoogleFolderId(null);
setSelectedGoogleFolderName(null);
}
else if (data.action === "picked")
{
console.log(data);
const mimeType = data.docs[0].mimeType;
if(mimeType === "application/vnd.google-apps.folder")
{
setSelectedGoogleFolderId(data.docs[0].id);
setSelectedGoogleFolderName(data.docs[0].name);
setErrorMessage(null)
}
else
{
setSelectedGoogleFolderId(null);
setSelectedGoogleFolderName(null);
setErrorMessage("You selected a file, but a folder is required.")
}
}
else
{
console.log("Called with un-recognized action:");
console.log(data);
}
},
});
};
useEffect(() =>
{
formikProps.setFieldValue("googleDriveAccessToken", googleToken);
formikProps.setFieldValue("googleDriveFolderId", selectedGoogleFolderId);
formikProps.setFieldValue("googleDriveFolderName", selectedGoogleFolderName);
}, [selectedGoogleFolderId, selectedGoogleFolderName])
return (
{selectedGoogleFolderName}