From 5902ca0201db9ee66f86064ac498f19305e3869b Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 19 Feb 2023 15:26:27 -0500 Subject: [PATCH 1/9] added modal to select source documentation --- frontend/src/Navigation.tsx | 31 ++++- frontend/src/api/docs.ts | 18 +++ frontend/src/models/misc.ts | 11 ++ frontend/src/preferences/SelectDocsModal.tsx | 122 +++++++++++++++++++ frontend/src/preferences/preferenceSlice.ts | 12 +- 5 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 frontend/src/api/docs.ts create mode 100644 frontend/src/preferences/SelectDocsModal.tsx diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index 2b4fd23..51990ea 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -6,8 +6,12 @@ import Info from './assets/info.svg'; import Link from './assets/link.svg'; import { ActiveState } from './models/misc'; import APIKeyModal from './preferences/APIKeyModal'; +import SelectDocsModal from './preferences/SelectDocsModal'; import { useSelector } from 'react-redux'; -import { selectApiKeyStatus } from './preferences/preferenceSlice'; +import { + selectApiKeyStatus, + selectSelectedDocsStatus, +} from './preferences/preferenceSlice'; import { useState } from 'react'; //TODO - Need to replace Chat button to open secondary nav with scrollable past chats option and new chat at top @@ -24,6 +28,11 @@ export default function Navigation({ const [apiKeyModalState, setApiKeyModalState] = useState( isApiKeySet ? 'INACTIVE' : 'ACTIVE', ); + + const isSelectedDocsSet = useSelector(selectSelectedDocsStatus); + const [selectedDocsModalState, setSelectedDocsModalState] = + useState(isSelectedDocsSet ? 'INACTIVE' : 'ACTIVE'); + return ( <>
-
+
{ @@ -59,6 +68,18 @@ export default function Navigation({ key

Reset Key

+ +
{ + setSelectedDocsModalState('ACTIVE'); + }} + > + key +

+ Select Source Documentation +

+
@@ -87,11 +108,17 @@ export default function Navigation({ > menu toggle + + ); } diff --git a/frontend/src/api/docs.ts b/frontend/src/api/docs.ts new file mode 100644 index 0000000..1a219ad --- /dev/null +++ b/frontend/src/api/docs.ts @@ -0,0 +1,18 @@ +import { Doc } from '../models/misc'; + +export async function getDocs(): Promise> { + //Fetch default source docs + const response = await fetch( + 'https://d3dg1063dc54p9.cloudfront.net/combined.json', + ); + const data = await response.json(); + + //Create array of Doc objects + const docs: Array = []; + + data.forEach((doc: Doc) => { + docs.push(doc); + }); + + return docs; +} diff --git a/frontend/src/models/misc.ts b/frontend/src/models/misc.ts index dbf21ae..5f9ed13 100644 --- a/frontend/src/models/misc.ts +++ b/frontend/src/models/misc.ts @@ -3,3 +3,14 @@ export type ActiveState = 'ACTIVE' | 'INACTIVE'; export type User = { avatar: string; }; + +export type Doc = { + name: string; + language: string; + version: string; + description: string; + fullName: string; + dat: string; + docLink: string; + model: string; +}; diff --git a/frontend/src/preferences/SelectDocsModal.tsx b/frontend/src/preferences/SelectDocsModal.tsx new file mode 100644 index 0000000..47d63ab --- /dev/null +++ b/frontend/src/preferences/SelectDocsModal.tsx @@ -0,0 +1,122 @@ +import { useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { ActiveState, Doc } from '../models/misc'; +import { setSelectedDocs, selectSelectedDocs } from './preferenceSlice'; +import { getDocs } from '../api/docs'; + +export default function APIKeyModal({ + modalState, + setModalState, + isCancellable = true, +}: { + modalState: ActiveState; + setModalState: (val: ActiveState) => void; + isCancellable?: boolean; +}) { + const dispatch = useDispatch(); + const [isError, setIsError] = useState(false); + const [docs, setDocs] = useState([]); + const [localSelectedDocs, setLocalSelectedDocs] = useState(null); + const [isDocsListOpen, setIsDocsListOpen] = useState(false); + + function handleSubmit() { + if (!localSelectedDocs) { + setIsError(true); + } else { + dispatch(setSelectedDocs(localSelectedDocs)); + setModalState('INACTIVE'); + setLocalSelectedDocs(null); + setIsError(false); + } + } + + function handleCancel() { + setSelectedDocs(null); + setIsError(false); + setModalState('INACTIVE'); + } + + useEffect(() => { + async function requestDocs() { + const data = await getDocs(); + setDocs(data); + } + + requestDocs(); + }, []); + + return ( +
+
+

Select Source Documentation

+

+ Please select the library of documentation that you would like to use + with our app. +

+
+
setIsDocsListOpen(!isDocsListOpen)} + > + {!localSelectedDocs ? ( +

Select

+ ) : ( +

+ {localSelectedDocs.name} {localSelectedDocs.version} +

+ )} +
+ {isDocsListOpen && ( +
+ {docs.map((doc, index) => { + if (doc.model) { + return ( +
{ + setLocalSelectedDocs(doc); + setIsDocsListOpen(false); + }} + className="h-10 w-full cursor-pointer border-x-2 border-b-2 hover:bg-gray-100" + > +

+ {doc.name} {doc.version} +

+
+ ); + } + })} +
+ )} +
+
+ {isCancellable && ( + + )} + {' '} + {isError && ( +

+ Please select source documentation. +

+ )} +
+
+
+ ); +} diff --git a/frontend/src/preferences/preferenceSlice.ts b/frontend/src/preferences/preferenceSlice.ts index 6121f9d..0323a5b 100644 --- a/frontend/src/preferences/preferenceSlice.ts +++ b/frontend/src/preferences/preferenceSlice.ts @@ -1,12 +1,15 @@ import { createSlice } from '@reduxjs/toolkit'; +import { Doc } from '../models/misc'; import store from '../store'; interface Preference { apiKey: string; + selectedDocs: Doc | null; } const initialState: Preference = { apiKey: '', + selectedDocs: null, }; export const prefSlice = createSlice({ @@ -16,10 +19,13 @@ export const prefSlice = createSlice({ setApiKey: (state, action) => { state.apiKey = action.payload; }, + setSelectedDocs: (state, action) => { + state.selectedDocs = action.payload; + }, }, }); -export const { setApiKey } = prefSlice.actions; +export const { setApiKey, setSelectedDocs } = prefSlice.actions; export default prefSlice.reducer; type RootState = ReturnType; @@ -27,3 +33,7 @@ type RootState = ReturnType; export const selectApiKey = (state: RootState) => state.preference.apiKey; export const selectApiKeyStatus = (state: RootState) => !!state.preference.apiKey; +export const selectSelectedDocs = (state: RootState) => + state.preference.selectedDocs; +export const selectSelectedDocsStatus = (state: RootState) => + !!state.preference.selectedDocs; From 112e7a247319c2f4bde2256b8c8d52b368b80c05 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 19 Feb 2023 15:42:56 -0500 Subject: [PATCH 2/9] removed unused import/export --- frontend/src/preferences/SelectDocsModal.tsx | 4 ++-- frontend/src/preferences/preferenceSlice.ts | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/preferences/SelectDocsModal.tsx b/frontend/src/preferences/SelectDocsModal.tsx index 47d63ab..26bd7f3 100644 --- a/frontend/src/preferences/SelectDocsModal.tsx +++ b/frontend/src/preferences/SelectDocsModal.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; import { ActiveState, Doc } from '../models/misc'; -import { setSelectedDocs, selectSelectedDocs } from './preferenceSlice'; +import { setSelectedDocs } from './preferenceSlice'; import { getDocs } from '../api/docs'; export default function APIKeyModal({ @@ -109,7 +109,7 @@ export default function APIKeyModal({ className="ml-auto h-10 w-20 rounded-lg bg-violet-800 text-white transition-all hover:bg-violet-700" > Save - {' '} + {isError && (

Please select source documentation. diff --git a/frontend/src/preferences/preferenceSlice.ts b/frontend/src/preferences/preferenceSlice.ts index 0323a5b..0ee3b8e 100644 --- a/frontend/src/preferences/preferenceSlice.ts +++ b/frontend/src/preferences/preferenceSlice.ts @@ -33,7 +33,5 @@ type RootState = ReturnType; export const selectApiKey = (state: RootState) => state.preference.apiKey; export const selectApiKeyStatus = (state: RootState) => !!state.preference.apiKey; -export const selectSelectedDocs = (state: RootState) => - state.preference.selectedDocs; export const selectSelectedDocsStatus = (state: RootState) => !!state.preference.selectedDocs; From db9a416ca048982349be1a5082641e5fe69c08df Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 19 Feb 2023 16:18:49 -0500 Subject: [PATCH 3/9] fixed about page margin --- frontend/src/About.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/About.tsx b/frontend/src/About.tsx index ddf6d8e..ca8ddd8 100644 --- a/frontend/src/About.tsx +++ b/frontend/src/About.tsx @@ -4,7 +4,7 @@ export default function About() { return ( //Parent div for all content shown through App.tsx routing needs to have this styling. Might change when state management is updated. -

+

About DocsGPT 🦖

From d8104381a55695d09a4e1776fe4181dd6cfba951 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 19 Feb 2023 17:07:38 -0500 Subject: [PATCH 4/9] small nav fix --- frontend/src/Navigation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index 51990ea..e7a4ffd 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -37,7 +37,7 @@ export default function Navigation({ <>

From f61fc718749e2c207501c2aa18f9f8283ae61bc6 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 19 Feb 2023 19:47:50 -0500 Subject: [PATCH 5/9] bug fix --- frontend/src/api/docs.ts | 28 ++++++----- frontend/src/preferences/SelectDocsModal.tsx | 50 +++++++++++--------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/frontend/src/api/docs.ts b/frontend/src/api/docs.ts index 1a219ad..9098052 100644 --- a/frontend/src/api/docs.ts +++ b/frontend/src/api/docs.ts @@ -1,18 +1,22 @@ import { Doc } from '../models/misc'; -export async function getDocs(): Promise> { - //Fetch default source docs - const response = await fetch( - 'https://d3dg1063dc54p9.cloudfront.net/combined.json', - ); - const data = await response.json(); +export async function getDocs(): Promise | null> { + try { + //Fetch default source docs + const response = await fetch( + 'https://d3dg1063dc54p9.cloudfront.net/combined.json', + ); + const data = await response.json(); - //Create array of Doc objects - const docs: Array = []; + //Create array of Doc objects + const docs: Array = []; - data.forEach((doc: Doc) => { - docs.push(doc); - }); + data.forEach((doc: Doc) => { + docs.push(doc); + }); - return docs; + return docs; + } catch (error) { + return null; + } } diff --git a/frontend/src/preferences/SelectDocsModal.tsx b/frontend/src/preferences/SelectDocsModal.tsx index 26bd7f3..3850daf 100644 --- a/frontend/src/preferences/SelectDocsModal.tsx +++ b/frontend/src/preferences/SelectDocsModal.tsx @@ -14,10 +14,10 @@ export default function APIKeyModal({ isCancellable?: boolean; }) { const dispatch = useDispatch(); - const [isError, setIsError] = useState(false); - const [docs, setDocs] = useState([]); + const [docs, setDocs] = useState(null); const [localSelectedDocs, setLocalSelectedDocs] = useState(null); const [isDocsListOpen, setIsDocsListOpen] = useState(false); + const [isError, setIsError] = useState(false); function handleSubmit() { if (!localSelectedDocs) { @@ -31,7 +31,7 @@ export default function APIKeyModal({ } function handleCancel() { - setSelectedDocs(null); + setLocalSelectedDocs(null); setIsError(false); setModalState('INACTIVE'); } @@ -71,25 +71,31 @@ export default function APIKeyModal({ )}
{isDocsListOpen && ( -
- {docs.map((doc, index) => { - if (doc.model) { - return ( -
{ - setLocalSelectedDocs(doc); - setIsDocsListOpen(false); - }} - className="h-10 w-full cursor-pointer border-x-2 border-b-2 hover:bg-gray-100" - > -

- {doc.name} {doc.version} -

-
- ); - } - })} +
+ {docs ? ( + docs.map((doc, index) => { + if (doc.model) { + return ( +
{ + setLocalSelectedDocs(doc); + setIsDocsListOpen(false); + }} + className="h-10 w-full cursor-pointer border-x-2 border-b-2 hover:bg-gray-100" + > +

+ {doc.name} {doc.version} +

+
+ ); + } + }) + ) : ( +
+

No default documentation.

+
+ )}
)}
From 80ada47df887ff571f50dac850dfbe5fc5fcbaf5 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 19 Feb 2023 19:49:21 -0500 Subject: [PATCH 6/9] fix --- frontend/src/api/docs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/api/docs.ts b/frontend/src/api/docs.ts index 9098052..6d93f36 100644 --- a/frontend/src/api/docs.ts +++ b/frontend/src/api/docs.ts @@ -1,6 +1,6 @@ import { Doc } from '../models/misc'; -export async function getDocs(): Promise | null> { +export async function getDocs(): Promise { try { //Fetch default source docs const response = await fetch( From dea949f772aafc6f869863025c674a6193abd10d Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Mon, 20 Feb 2023 14:22:11 -0500 Subject: [PATCH 7/9] Moved Doc type to selectDocsApi Moved /api/docs.ts to /preference/selectDocsApi.ts Added all source docs to redux --- frontend/src/Navigation.tsx | 11 +++---- frontend/src/api/docs.ts | 22 ------------- frontend/src/models/misc.ts | 11 ------- frontend/src/preferences/SelectDocsModal.tsx | 17 ++++++---- frontend/src/preferences/preferenceSlice.ts | 13 ++++++-- frontend/src/preferences/selectDocsApi.ts | 33 ++++++++++++++++++++ 6 files changed, 60 insertions(+), 47 deletions(-) delete mode 100644 frontend/src/api/docs.ts create mode 100644 frontend/src/preferences/selectDocsApi.ts diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index e7a4ffd..cfc7a82 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -108,17 +108,16 @@ export default function Navigation({ > menu toggle - - + ); } diff --git a/frontend/src/api/docs.ts b/frontend/src/api/docs.ts deleted file mode 100644 index 6d93f36..0000000 --- a/frontend/src/api/docs.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Doc } from '../models/misc'; - -export async function getDocs(): Promise { - try { - //Fetch default source docs - const response = await fetch( - 'https://d3dg1063dc54p9.cloudfront.net/combined.json', - ); - const data = await response.json(); - - //Create array of Doc objects - const docs: Array = []; - - data.forEach((doc: Doc) => { - docs.push(doc); - }); - - return docs; - } catch (error) { - return null; - } -} diff --git a/frontend/src/models/misc.ts b/frontend/src/models/misc.ts index 5f9ed13..dbf21ae 100644 --- a/frontend/src/models/misc.ts +++ b/frontend/src/models/misc.ts @@ -3,14 +3,3 @@ export type ActiveState = 'ACTIVE' | 'INACTIVE'; export type User = { avatar: string; }; - -export type Doc = { - name: string; - language: string; - version: string; - description: string; - fullName: string; - dat: string; - docLink: string; - model: string; -}; diff --git a/frontend/src/preferences/SelectDocsModal.tsx b/frontend/src/preferences/SelectDocsModal.tsx index 3850daf..91a60ac 100644 --- a/frontend/src/preferences/SelectDocsModal.tsx +++ b/frontend/src/preferences/SelectDocsModal.tsx @@ -1,8 +1,13 @@ import { useEffect, useState } from 'react'; -import { useDispatch } from 'react-redux'; -import { ActiveState, Doc } from '../models/misc'; -import { setSelectedDocs } from './preferenceSlice'; -import { getDocs } from '../api/docs'; +import { useDispatch, useSelector } from 'react-redux'; +import { ActiveState } from '../models/misc'; +import { Doc } from './selectDocsApi'; +import { + setSelectedDocs, + setSourceDocs, + selectSourceDocs, +} from './preferenceSlice'; +import { getDocs } from './selectDocsApi'; export default function APIKeyModal({ modalState, @@ -14,7 +19,7 @@ export default function APIKeyModal({ isCancellable?: boolean; }) { const dispatch = useDispatch(); - const [docs, setDocs] = useState(null); + const docs = useSelector(selectSourceDocs); const [localSelectedDocs, setLocalSelectedDocs] = useState(null); const [isDocsListOpen, setIsDocsListOpen] = useState(false); const [isError, setIsError] = useState(false); @@ -39,7 +44,7 @@ export default function APIKeyModal({ useEffect(() => { async function requestDocs() { const data = await getDocs(); - setDocs(data); + dispatch(setSourceDocs(data)); } requestDocs(); diff --git a/frontend/src/preferences/preferenceSlice.ts b/frontend/src/preferences/preferenceSlice.ts index 0ee3b8e..a501df5 100644 --- a/frontend/src/preferences/preferenceSlice.ts +++ b/frontend/src/preferences/preferenceSlice.ts @@ -1,15 +1,17 @@ import { createSlice } from '@reduxjs/toolkit'; -import { Doc } from '../models/misc'; +import { Doc } from './selectDocsApi'; import store from '../store'; interface Preference { apiKey: string; selectedDocs: Doc | null; + sourceDocs: Doc[] | null; } const initialState: Preference = { apiKey: '', selectedDocs: null, + sourceDocs: null, }; export const prefSlice = createSlice({ @@ -21,11 +23,16 @@ export const prefSlice = createSlice({ }, setSelectedDocs: (state, action) => { state.selectedDocs = action.payload; + console.log('setSelectedDocs', state.selectedDocs); + }, + setSourceDocs: (state, action) => { + state.sourceDocs = action.payload; + console.log('setSourceDocs', state.sourceDocs); }, }, }); -export const { setApiKey, setSelectedDocs } = prefSlice.actions; +export const { setApiKey, setSelectedDocs, setSourceDocs } = prefSlice.actions; export default prefSlice.reducer; type RootState = ReturnType; @@ -35,3 +42,5 @@ export const selectApiKeyStatus = (state: RootState) => !!state.preference.apiKey; export const selectSelectedDocsStatus = (state: RootState) => !!state.preference.selectedDocs; +export const selectSourceDocs = (state: RootState) => + state.preference.sourceDocs; diff --git a/frontend/src/preferences/selectDocsApi.ts b/frontend/src/preferences/selectDocsApi.ts new file mode 100644 index 0000000..5c700cf --- /dev/null +++ b/frontend/src/preferences/selectDocsApi.ts @@ -0,0 +1,33 @@ +//Exporting Doc type from here since its the first place its used and seems needless to make an entire file for it. +export type Doc = { + name: string; + language: string; + version: string; + description: string; + fullName: string; + dat: string; + docLink: string; + model: string; +}; + +//Fetches all JSON objects from the source. We only use the objects with the "model" property in SelectDocsModal.tsx. Hopefully can clean up the source file later. +export async function getDocs(): Promise { + try { + //Fetch default source docs + const response = await fetch( + 'https://d3dg1063dc54p9.cloudfront.net/combined.json', + ); + const data = await response.json(); + + //Create array of Doc objects + const docs: Doc[] = []; + + data.forEach((doc: Doc) => { + docs.push(doc); + }); + + return docs; + } catch (error) { + return null; + } +} From 8ee34d866025458e66281a4419d77c935d5c6459 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Mon, 20 Feb 2023 14:44:59 -0500 Subject: [PATCH 8/9] little change --- frontend/src/preferences/SelectDocsModal.tsx | 3 +-- frontend/src/preferences/selectDocsApi.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/src/preferences/SelectDocsModal.tsx b/frontend/src/preferences/SelectDocsModal.tsx index 91a60ac..691f90c 100644 --- a/frontend/src/preferences/SelectDocsModal.tsx +++ b/frontend/src/preferences/SelectDocsModal.tsx @@ -1,13 +1,12 @@ import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { ActiveState } from '../models/misc'; -import { Doc } from './selectDocsApi'; import { setSelectedDocs, setSourceDocs, selectSourceDocs, } from './preferenceSlice'; -import { getDocs } from './selectDocsApi'; +import { getDocs, Doc } from './selectDocsApi'; export default function APIKeyModal({ modalState, diff --git a/frontend/src/preferences/selectDocsApi.ts b/frontend/src/preferences/selectDocsApi.ts index 5c700cf..fe781e1 100644 --- a/frontend/src/preferences/selectDocsApi.ts +++ b/frontend/src/preferences/selectDocsApi.ts @@ -22,8 +22,8 @@ export async function getDocs(): Promise { //Create array of Doc objects const docs: Doc[] = []; - data.forEach((doc: Doc) => { - docs.push(doc); + data.forEach((doc: object) => { + docs.push(doc as Doc); }); return docs; From 708c11ba78a380c012f6c1c0e8796be58b0959bf Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Mon, 20 Feb 2023 14:53:53 -0500 Subject: [PATCH 9/9] removed logging --- frontend/src/preferences/preferenceSlice.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/preferences/preferenceSlice.ts b/frontend/src/preferences/preferenceSlice.ts index a501df5..4c8a95b 100644 --- a/frontend/src/preferences/preferenceSlice.ts +++ b/frontend/src/preferences/preferenceSlice.ts @@ -23,11 +23,9 @@ export const prefSlice = createSlice({ }, setSelectedDocs: (state, action) => { state.selectedDocs = action.payload; - console.log('setSelectedDocs', state.selectedDocs); }, setSourceDocs: (state, action) => { state.sourceDocs = action.payload; - console.log('setSourceDocs', state.sourceDocs); }, }, });