From 2b76fc11079e39ddd1ac2a1966986a99d8f109a4 Mon Sep 17 00:00:00 2001 From: Steve Cassidy Date: Tue, 10 Dec 2024 10:25:02 +1300 Subject: [PATCH 1/4] tweak to autoincrementer field settings Signed-off-by: Steve Cassidy --- .../components/autoincrement/edit-form.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/gui/components/autoincrement/edit-form.tsx b/app/src/gui/components/autoincrement/edit-form.tsx index db83ef1c6..e597eb54d 100644 --- a/app/src/gui/components/autoincrement/edit-form.tsx +++ b/app/src/gui/components/autoincrement/edit-form.tsx @@ -80,7 +80,6 @@ export const AutoIncrementEditForm = ({ ); return ranges; }, - initialData: [], enabled: true, }); @@ -207,20 +206,25 @@ type IncremenenterRangeProps = { * @param props component props */ const IncrementerRange = (props: IncremenenterRangeProps) => { - const [start, setStart] = useState(props.range.start); - const [stop, setStop] = useState(props.range.stop); + const [start, setStart] = useState(props.range.start); + const [stop, setStop] = useState(props.range.stop); const handleStartChange = (event: any) => { + if (event.target.value === '') { + // set start but don't update the range + setStart(''); + return; + } const newStart = parseInt(event.target.value); if (newStart >= 0) { setStart(newStart); if (newStart >= props.range.stop) { // initialise a range of 100 if they enter a start > stop - setStop(newStart + 100); + setStop(newStart + 99); props.updateRange({ ...props.range, start: newStart, - stop: newStart + 100, + stop: newStart + 99, }); } else { props.updateRange({ @@ -232,6 +236,11 @@ const IncrementerRange = (props: IncremenenterRangeProps) => { }; const handleStopChange = (event: any) => { + if (event.target.value === '') { + // set stop but don't update the range + setStop(''); + return; + } const newStop = parseInt(event.target.value); if (newStop > props.range.start) { setStop(newStop); From c2d5a6d69546fc68335dd162d70f7e9fb70e94d3 Mon Sep 17 00:00:00 2001 From: Steve Cassidy Date: Tue, 10 Dec 2024 10:47:52 +1300 Subject: [PATCH 2/4] lint + build fixes Signed-off-by: Steve Cassidy --- app/src/gui/components/autoincrement/edit-form.tsx | 8 +++++--- app/src/gui/components/record/form.tsx | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/gui/components/autoincrement/edit-form.tsx b/app/src/gui/components/autoincrement/edit-form.tsx index e597eb54d..1ec8e3567 100644 --- a/app/src/gui/components/autoincrement/edit-form.tsx +++ b/app/src/gui/components/autoincrement/edit-form.tsx @@ -111,9 +111,11 @@ export const AutoIncrementEditForm = ({ const updateRange = (index: number) => { return (range: LocalAutoIncrementRange) => { - const rangesCopy = [...ranges]; - rangesCopy[index] = range; - updateRanges(rangesCopy); + if (ranges) { + const rangesCopy = [...ranges]; + rangesCopy[index] = range; + updateRanges(rangesCopy); + } }; }; diff --git a/app/src/gui/components/record/form.tsx b/app/src/gui/components/record/form.tsx index ad79cc530..51744e610 100644 --- a/app/src/gui/components/record/form.tsx +++ b/app/src/gui/components/record/form.tsx @@ -45,7 +45,6 @@ import { upsertFAIMSData, } from '@faims3/data-model'; import {NavigateFunction} from 'react-router-dom'; -import {DEBUG_APP} from '../../../buildconfig'; import * as ROUTES from '../../../constants/routes'; import {store} from '../../../context/store'; import {getFieldPersistentData} from '../../../local-data/field-persistent'; From 8e140e8bc9b1ab0881b2f85ba77fc3bfa6dbcc8c Mon Sep 17 00:00:00 2001 From: Steve Cassidy Date: Wed, 11 Dec 2024 11:16:17 +1300 Subject: [PATCH 3/4] try to deal with offline project listings - not working Signed-off-by: Steve Cassidy --- app/src/context/functions.tsx | 4 ++- app/src/context/projects-context.tsx | 36 +++++++++++++++++++ app/src/dbs/projects-db.tsx | 2 ++ .../gui/components/workspace/notebooks.tsx | 2 ++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/src/context/functions.tsx b/app/src/context/functions.tsx index 77fdb08e5..30d17cffb 100644 --- a/app/src/context/functions.tsx +++ b/app/src/context/functions.tsx @@ -90,9 +90,11 @@ const getProjects = async (url: string, token: string) => { headers: { Authorization: `Bearer ${token}`, }, + }).catch(() => { + return null; }); - if (!response.ok) { + if (response === null || (response && !response.ok)) { console.error(`Error fetching projects from ${url}`); return [] as ProjectObject[]; } diff --git a/app/src/context/projects-context.tsx b/app/src/context/projects-context.tsx index a6826f777..6e6fc95d5 100644 --- a/app/src/context/projects-context.tsx +++ b/app/src/context/projects-context.tsx @@ -7,6 +7,8 @@ import { import {activate_project} from '../sync/process-initialization'; import {ProjectExtended} from '../types/project'; import {getLocalActiveMap, getProjectMap, getRemoteProjects} from './functions'; +import {getAvailableProjectsFromListing} from '../sync/projects'; +import {getAllListingIDs, getListing} from '../sync/state'; export const ProjectsContext = createContext<{ projects: ProjectExtended[]; @@ -30,6 +32,7 @@ export const ProjectsContext = createContext<{ export function ProjectsProvider({children}: {children: ReactNode}) { const [projects, setProjects] = useState([]); + console.debug('projectsProvider', projects); useEffect(() => { initProjects(); }, []); @@ -52,6 +55,36 @@ export function ProjectsProvider({children}: {children: ReactNode}) { const localActiveMap = await getLocalActiveMap(); + // if we're offline, remote projects is empty so just + // return the local ones we know already + + if (remoteProjects.length === 0) { + const allStoredProjects: ProjectExtended[] = []; + getAllListingIDs().forEach(async (listing_id: string) => { + const storedProjects = + await getAvailableProjectsFromListing(listing_id); + console.debug('storedProjects', storedProjects); + // storedProjects is ProjectInformation[] and we need ProjectExtended[] + const listing = await getListing(listing_id); + allStoredProjects.concat( + storedProjects.map(project => { + return { + ...project, + _id: project.project_id, + conductor_url: listing.listing.conductor_url, + listing: listing_id, + activated: localActiveMap.has(project.project_id), + sync: localProjectsMap.get(project.project_id)?.sync ?? false, + // do we also need the two database connections here??? + }; + }) + ); + }); + console.debug('allStoredProjects', allStoredProjects); + setProjects(allStoredProjects); + return; + } + for (const remoteProject of remoteProjects) { const activated = localProjectsMap.get(remoteProject._id)?.activated ?? @@ -70,6 +103,7 @@ export function ProjectsProvider({children}: {children: ReactNode}) { }); } + console.debug('setting projects', [...newProjectsMap.values()]); setProjects([...newProjectsMap.values()]); }; @@ -87,6 +121,8 @@ export function ProjectsProvider({children}: {children: ReactNode}) { const projectsMap = getProjectMap(projects); const newProjectsMap = getProjectMap(projects); + if (remoteProjects.length === 0) return; + // update project list, preserve activated and sync states from existing list for (const remoteProject of remoteProjects) { newProjectsMap.set(remoteProject._id, { diff --git a/app/src/dbs/projects-db.tsx b/app/src/dbs/projects-db.tsx index 58bf5b12c..dffda1846 100644 --- a/app/src/dbs/projects-db.tsx +++ b/app/src/dbs/projects-db.tsx @@ -35,6 +35,7 @@ export const updateProjectsDB = async (projects: ProjectExtended[]) => * @returns A promise that resolves when the project is activated. */ export const activateProjectDB = async (_id: string) => { + console.debug('activateProjectDB', await db.info()); const doc = await db.get(_id); await db.put({ @@ -73,6 +74,7 @@ export const setSyncProjectDB = async (_id: string, sync: boolean) => { * @returns An array of local projects. */ export const getProjectsDB = async () => { + console.debug('getProjectsDB', await db.info()); const {rows} = await db.allDocs({include_docs: true}); return rows.map(row => row?.doc?.project).filter(x => x !== undefined); diff --git a/app/src/gui/components/workspace/notebooks.tsx b/app/src/gui/components/workspace/notebooks.tsx index 36a550630..101b6f0a2 100644 --- a/app/src/gui/components/workspace/notebooks.tsx +++ b/app/src/gui/components/workspace/notebooks.tsx @@ -69,6 +69,8 @@ export default function NoteBooks() { const activatedProjects = projects.filter(({activated}) => activated); + console.debug('PPPPP', projects, activatedProjects); + const [tabID, setTabID] = useState('1'); const history = useNavigate(); From 9299089ba0a7bec321b72bfc894a1731c3127dd2 Mon Sep 17 00:00:00 2001 From: Steve Cassidy Date: Thu, 12 Dec 2024 09:48:00 +1300 Subject: [PATCH 4/4] Revert "try to deal with offline project listings - not working" Now fixed in another PR. Signed-off-by: Steve Cassidy --- app/src/context/functions.tsx | 4 +-- app/src/context/projects-context.tsx | 36 ------------------- app/src/dbs/projects-db.tsx | 2 -- .../gui/components/workspace/notebooks.tsx | 2 -- 4 files changed, 1 insertion(+), 43 deletions(-) diff --git a/app/src/context/functions.tsx b/app/src/context/functions.tsx index 30d17cffb..77fdb08e5 100644 --- a/app/src/context/functions.tsx +++ b/app/src/context/functions.tsx @@ -90,11 +90,9 @@ const getProjects = async (url: string, token: string) => { headers: { Authorization: `Bearer ${token}`, }, - }).catch(() => { - return null; }); - if (response === null || (response && !response.ok)) { + if (!response.ok) { console.error(`Error fetching projects from ${url}`); return [] as ProjectObject[]; } diff --git a/app/src/context/projects-context.tsx b/app/src/context/projects-context.tsx index 6e6fc95d5..a6826f777 100644 --- a/app/src/context/projects-context.tsx +++ b/app/src/context/projects-context.tsx @@ -7,8 +7,6 @@ import { import {activate_project} from '../sync/process-initialization'; import {ProjectExtended} from '../types/project'; import {getLocalActiveMap, getProjectMap, getRemoteProjects} from './functions'; -import {getAvailableProjectsFromListing} from '../sync/projects'; -import {getAllListingIDs, getListing} from '../sync/state'; export const ProjectsContext = createContext<{ projects: ProjectExtended[]; @@ -32,7 +30,6 @@ export const ProjectsContext = createContext<{ export function ProjectsProvider({children}: {children: ReactNode}) { const [projects, setProjects] = useState([]); - console.debug('projectsProvider', projects); useEffect(() => { initProjects(); }, []); @@ -55,36 +52,6 @@ export function ProjectsProvider({children}: {children: ReactNode}) { const localActiveMap = await getLocalActiveMap(); - // if we're offline, remote projects is empty so just - // return the local ones we know already - - if (remoteProjects.length === 0) { - const allStoredProjects: ProjectExtended[] = []; - getAllListingIDs().forEach(async (listing_id: string) => { - const storedProjects = - await getAvailableProjectsFromListing(listing_id); - console.debug('storedProjects', storedProjects); - // storedProjects is ProjectInformation[] and we need ProjectExtended[] - const listing = await getListing(listing_id); - allStoredProjects.concat( - storedProjects.map(project => { - return { - ...project, - _id: project.project_id, - conductor_url: listing.listing.conductor_url, - listing: listing_id, - activated: localActiveMap.has(project.project_id), - sync: localProjectsMap.get(project.project_id)?.sync ?? false, - // do we also need the two database connections here??? - }; - }) - ); - }); - console.debug('allStoredProjects', allStoredProjects); - setProjects(allStoredProjects); - return; - } - for (const remoteProject of remoteProjects) { const activated = localProjectsMap.get(remoteProject._id)?.activated ?? @@ -103,7 +70,6 @@ export function ProjectsProvider({children}: {children: ReactNode}) { }); } - console.debug('setting projects', [...newProjectsMap.values()]); setProjects([...newProjectsMap.values()]); }; @@ -121,8 +87,6 @@ export function ProjectsProvider({children}: {children: ReactNode}) { const projectsMap = getProjectMap(projects); const newProjectsMap = getProjectMap(projects); - if (remoteProjects.length === 0) return; - // update project list, preserve activated and sync states from existing list for (const remoteProject of remoteProjects) { newProjectsMap.set(remoteProject._id, { diff --git a/app/src/dbs/projects-db.tsx b/app/src/dbs/projects-db.tsx index dffda1846..58bf5b12c 100644 --- a/app/src/dbs/projects-db.tsx +++ b/app/src/dbs/projects-db.tsx @@ -35,7 +35,6 @@ export const updateProjectsDB = async (projects: ProjectExtended[]) => * @returns A promise that resolves when the project is activated. */ export const activateProjectDB = async (_id: string) => { - console.debug('activateProjectDB', await db.info()); const doc = await db.get(_id); await db.put({ @@ -74,7 +73,6 @@ export const setSyncProjectDB = async (_id: string, sync: boolean) => { * @returns An array of local projects. */ export const getProjectsDB = async () => { - console.debug('getProjectsDB', await db.info()); const {rows} = await db.allDocs({include_docs: true}); return rows.map(row => row?.doc?.project).filter(x => x !== undefined); diff --git a/app/src/gui/components/workspace/notebooks.tsx b/app/src/gui/components/workspace/notebooks.tsx index 101b6f0a2..36a550630 100644 --- a/app/src/gui/components/workspace/notebooks.tsx +++ b/app/src/gui/components/workspace/notebooks.tsx @@ -69,8 +69,6 @@ export default function NoteBooks() { const activatedProjects = projects.filter(({activated}) => activated); - console.debug('PPPPP', projects, activatedProjects); - const [tabID, setTabID] = useState('1'); const history = useNavigate();