diff --git a/src/components/DataSync/DataSync.tsx b/src/components/DataSync/DataSync.tsx index 6f907e3..dc9be75 100644 --- a/src/components/DataSync/DataSync.tsx +++ b/src/components/DataSync/DataSync.tsx @@ -626,6 +626,14 @@ export const DataSyncModal: FC = ({ {/* Form Group for user initiated sync events: on add new log, on edit log, on add entry, on edit entry, on add field, on edit field */} {"Sync on user interactions:"} + { + setSyncOnAddNewLog(e.target.checked); + }} + /> { // todo: remove log from data sync state store.dispatch(removeLog({ logId: log.id })); + store.dispatch(removeGoogleDriveLogSheet(log.id)); }; export interface onDeleteFieldParams { diff --git a/src/containers/Home/Home.tsx b/src/containers/Home/Home.tsx index 8fbdc20..45d14b9 100644 --- a/src/containers/Home/Home.tsx +++ b/src/containers/Home/Home.tsx @@ -10,6 +10,7 @@ import { addLogField, ADD_LOG_ACTION, initialFieldStates, + initialLogState, LogEntry, LogField, removeLog, @@ -41,12 +42,17 @@ import { PRIMARY, SAVE, SECONDARY, + SYNC_LOG, TEXT, TEXT_DANGER, UPDATED_AT, } from "../../strings"; import { SetToast } from "../../components/Toaster"; import { parseCSV } from "../../utils"; +import { useAuthenticated } from "../../store/Session"; +import { addGoogleDriveLogSheet, DataSyncState, getLogSheets, useDataSync } from "../../store/DataSync"; +import { initNewLogSheet, setLogSheetIds } from "../../services/DataSync"; +import { handleError } from "../../components/DataSync"; export const TRACKER_KEEPER = "Tracker Keeper"; export const YOUR_LOGS = "Your Logs"; @@ -62,15 +68,47 @@ export const RESTORE_LOG = "Restore log from CSV"; export const LOG_ENTRIES = "Log Entries"; export const LOG_FIELDS = "Log Fields"; -export const onAddLog = (id: string, name: string) => { - const log = { +export interface onAddLogParams { + id: string; + name: string; + syncLog: boolean; + authenticated?: boolean; + dataSyncState?: DataSyncState; +} +export const onAddLog = async ({ id, name, - fields: {}, - entries: {}, + syncLog, + authenticated, + dataSyncState, +}: onAddLogParams) => { + const log = { + ...initialLogState, + name, + id, }; store.dispatch(addLog({ log })); - // todo: add to data sync state; init new log sheet + + if (syncLog && authenticated && dataSyncState?.syncEnabled && dataSyncState?.syncSettings?.onAddNewLog) { + const sync = dataSyncState[dataSyncState.syncMethod]; + if (sync?.folderId) { + const sheet = await initNewLogSheet({ + onError: handleError, + syncId: dataSyncState.syncId, + log, + folderId: sync.folderId, + }); + await store.dispatch(addGoogleDriveLogSheet({ + [id]: sheet.id, + })); + const logSheetIds = getLogSheets(store.getState()); + setLogSheetIds({ + onError: handleError, + logSheetId: sync.logSheetId, + logSheetIds, + }); + } + } }; export interface HomeProps { @@ -79,6 +117,9 @@ export interface HomeProps { export const Home: FC = ({ setToast }): ReactElement => { const navigate = useNavigate(); + const authenticated = useAuthenticated() + const dataSyncState = useDataSync(); + const isNewLogModalOpen = window.location.hash === "#/new"; const [showSidebar, setShowSidebar] = React.useState(false); const [showModal, setShowModal] = React.useState(isNewLogModalOpen); @@ -89,6 +130,7 @@ export const Home: FC = ({ setToast }): ReactElement => { const [restoredEntries, setRestoredEntries] = React.useState([]); const [newLogId, setNewLogId] = React.useState(EMPTY); const [newLogName, setNewLogName] = React.useState(EMPTY); + const [syncLog, setSyncLog] = React.useState(false); const logs = useGetLogsArray(); if ( @@ -240,6 +282,16 @@ export const Home: FC = ({ setToast }): ReactElement => { onChange={(e) => setRestoreLog(e.target.checked)} /> + {dataSyncState.syncEnabled && dataSyncState.syncSettings.onAddEntry && ( + + setSyncLog(e.target.checked)} + /> + + )} {restoreLog && ( <> @@ -344,9 +396,15 @@ export const Home: FC = ({ setToast }): ReactElement => { (restoreLog && (!restoredFields.length || !restoredEntries.length)) } - onClick={() => { + onClick={async () => { const newId = uuidv4(); - onAddLog(newId, newLogName); + await onAddLog({ + id: newId, + name: newLogName, + syncLog, + authenticated, + dataSyncState, + }); setNewLogId(newId); if (restoreLog) { Object.values(restoredFields).forEach( @@ -371,6 +429,8 @@ export const Home: FC = ({ setToast }): ReactElement => { ); } ); + } else { + navigate(getEditLogURL(newId)); } setToast({ diff --git a/src/services/DataSync/DataSync.ts b/src/services/DataSync/DataSync.ts index f5a10fc..f23a557 100644 --- a/src/services/DataSync/DataSync.ts +++ b/src/services/DataSync/DataSync.ts @@ -418,7 +418,11 @@ export const initNewLogSheet = async ({ for (const key in newSheetData) { if (key === "fields" || key === "entries" || key === "recurrence") continue; if (Object.prototype.hasOwnProperty.call(newSheetData, key)) { - newSheetValues.push([key, newSheetData[key]]); + if (Array.isArray(newSheetData[key]) || typeof newSheetData[key] === "object") { + newSheetValues.push([key, JSON.stringify(newSheetData[key])]); + } else { + newSheetValues.push([key, newSheetData[key]]); + } } } if (log.recurrence) { diff --git a/src/store/DataSync/index.ts b/src/store/DataSync/index.ts index ee3cd65..0a5184c 100644 --- a/src/store/DataSync/index.ts +++ b/src/store/DataSync/index.ts @@ -41,6 +41,15 @@ export { useGoogleDriveLogSheets, useSyncSettings, + getDataSync, + getSyncEnabled, + getSyncMethod, + getSyncId, + getSync, + getLogSheetId, + getLogSheets, + getLogSheet, + SyncFrequency, } from "./reducer"; diff --git a/src/store/DataSync/reducer.ts b/src/store/DataSync/reducer.ts index 714f7c2..27c2257 100644 --- a/src/store/DataSync/reducer.ts +++ b/src/store/DataSync/reducer.ts @@ -140,8 +140,7 @@ export const dataSyncSlice: Slice< }; }, [REMOVE_GOOGLE_DRIVE_LOG_SHEET]: (state, action) => { - const { logSheetId } = action.payload; - delete state.googleDrive.logSheets[logSheetId]; + delete state.googleDrive.logSheets[action.payload]; }, [EDIT_SYNC_SETTINGS]: (state, action) => { state.syncSettings = action.payload; @@ -218,3 +217,37 @@ export const useSyncSettings = (): SyncSettings => { const dataSync = useDataSync(); return dataSync.syncSettings; }; + +// Selectors +export const getDataSync = (state: any): DataSyncState => { + return state[dataSyncSliceName]; +} + +export const getSyncEnabled = (state: any): boolean => { + return getDataSync(state).syncEnabled; +} + +export const getSyncId = (state: any): string => { + return getDataSync(state).syncId; +} + +export const getSyncMethod = (state: any): string => { + return getDataSync(state).syncMethod; +} + +export const getSync = (state: any) => { + const method = getSyncMethod(state); + return (getDataSync(state) as any)[method]; +} + +export const getLogSheetId = (state: any): string => { + return getSync(state).logSheetId; +} + +export const getLogSheets = (state: any): { [logId: string]: LogSheet } => { + return getSync(state).logSheets; +} + +export const getLogSheet = (state: any, logId: string): LogSheet => { + return getLogSheets(state)[logId] || {}; +} diff --git a/src/strings.ts b/src/strings.ts index 3437e0b..0a65350 100644 --- a/src/strings.ts +++ b/src/strings.ts @@ -103,6 +103,7 @@ export const OOPS = "Oops!"; export const LOG_NOT_FOUND = "Log not found"; export const DATA = "Data"; export const CSV = "CSV"; +export const SYNC_LOG = "Sync Log"; // Route Strings export const WILDCARD = "*";