/* * 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}
{errorMessage}
); } GoogleDriveFolderPicker.defaultProps = { showDefaultFoldersView: true, showSharedDrivesView: true };