From aae847791cca7cc89dd9bc7784d99a2931ddf540 Mon Sep 17 00:00:00 2001
From: Christopher Loverich <1010084+cloverich@users.noreply.github.com>
Date: Sun, 21 Jan 2024 07:33:55 -0800
Subject: [PATCH] pre-select current or active journals
- put search store into context (todo: refactor component drilling to pull from context)
- when creating new documents, if the search is scoped to a journal, default the new document to the selected journal
- when creating new documents, if search is NOT scoped, default to the first ACTIVE journal
---
src/container.tsx | 30 ++++++++++++++++----------
src/preload/client/journals.ts | 1 +
src/views/documents/SearchStore.ts | 11 ++++++++++
src/views/edit/index.tsx | 6 +++++-
src/views/edit/useEditableDocument.ts | 31 ++++++++++++++++++++++-----
5 files changed, 62 insertions(+), 17 deletions(-)
diff --git a/src/container.tsx b/src/container.tsx
index 53f7751..eddcf16 100644
--- a/src/container.tsx
+++ b/src/container.tsx
@@ -13,7 +13,10 @@ import { Alert, Pane } from "evergreen-ui";
import { Routes, Route, Navigate } from "react-router-dom";
import { useSearchParams } from "react-router-dom";
import useClient from "./hooks/useClient";
-import { SearchV2Store } from "./views/documents/SearchStore";
+import {
+ SearchV2Store,
+ SearchStoreContext,
+} from "./views/documents/SearchStore";
export default observer(function Container() {
const { journalsStore, loading, loadingErr } = useJournalsLoader();
@@ -63,16 +66,21 @@ export default observer(function Container() {
return (
-
-
- } path="journals" />
- } path="preferences" />
- } path="edit/new" />
- } path="edit/:document" />
- } path="documents" />
- } />
-
-
+
+
+
+ } path="journals" />
+ } path="preferences" />
+ } path="edit/new" />
+ } path="edit/:document" />
+ }
+ path="documents"
+ />
+ } />
+
+
+
);
});
diff --git a/src/preload/client/journals.ts b/src/preload/client/journals.ts
index 0177352..9c42c59 100644
--- a/src/preload/client/journals.ts
+++ b/src/preload/client/journals.ts
@@ -48,6 +48,7 @@ export class JournalsClient {
};
remove = (journal: { id: string }): Promise => {
+ // TODO: ensure there is always at least one journal. Deleting the last journal breaks the app.
this.db
.prepare("delete from journals where id = :id")
.run({ id: journal.id });
diff --git a/src/views/documents/SearchStore.ts b/src/views/documents/SearchStore.ts
index d6b6e5a..0893d4f 100644
--- a/src/views/documents/SearchStore.ts
+++ b/src/views/documents/SearchStore.ts
@@ -1,3 +1,4 @@
+import { createContext } from "react";
import { IClient } from "../../hooks/useClient";
import { observable, IObservableArray, computed, action } from "mobx";
import { JournalsStore } from "../../hooks/stores/journals";
@@ -19,6 +20,8 @@ interface SearchQuery {
limit?: number;
}
+export const SearchStoreContext = createContext(null as any);
+
export class SearchV2Store {
@observable docs: SearchItem[] = [];
@observable loading = true;
@@ -156,6 +159,14 @@ export class SearchV2Store {
this.addTokens(searchStr);
};
+ @computed get selectedJournals(): string[] {
+ // Grab the journal names from the tokens
+ // todo: Typescript doesn't know when I filter to type === 'in' its InTokens
+ return this._tokens
+ .filter((t) => t.type === "in")
+ .map((t) => t.value) as string[];
+ }
+
@computed
get searchTokens() {
return this.tagSeachStore.searchTokens;
diff --git a/src/views/edit/index.tsx b/src/views/edit/index.tsx
index d21ae04..b82c2cf 100644
--- a/src/views/edit/index.tsx
+++ b/src/views/edit/index.tsx
@@ -14,13 +14,17 @@ import { JournalsStoreContext } from "../../hooks/useJournalsLoader";
import Toolbar from "./toolbar";
import { useParams, useNavigate } from "react-router-dom";
import { DebugView } from "./DebugView";
+import { SearchStoreContext } from "../documents/SearchStore";
// Loads document, with loading and error placeholders
function DocumentLoadingContainer() {
const journalsStore = useContext(JournalsStoreContext);
+ const searchStore = useContext(SearchStoreContext);
const { document: documentId } = useParams();
+
const { document, loadingError } = useEditableDocument(
- journalsStore.journals,
+ searchStore,
+ journalsStore,
documentId,
);
diff --git a/src/views/edit/useEditableDocument.ts b/src/views/edit/useEditableDocument.ts
index be80d93..a97714b 100644
--- a/src/views/edit/useEditableDocument.ts
+++ b/src/views/edit/useEditableDocument.ts
@@ -2,12 +2,36 @@ import React from "react";
import { JournalResponse } from "../../preload/client/journals";
import useClient from "../../hooks/useClient";
import { EditableDocument } from "./EditableDocument";
+import { SearchV2Store } from "../documents/SearchStore";
+import { JournalsStore } from "../../hooks/stores/journals";
+
+/**
+ * Determines the default journal to use when creating a new document.
+ *
+ * todo(test): When one or multiple journals are selected, returns the first
+ * todo(test): When no journals are selected, returns the first active journal
+ * todo(test): When archived journal selected, returns the selected (archived) journal
+ */
+function defaultJournal(selectedJournals: string[], jstore: JournalsStore) {
+ const selectedId = jstore.journals.find((j) =>
+ selectedJournals.includes(j.name),
+ )?.id;
+
+ if (selectedId) {
+ return selectedId;
+ } else {
+ // todo: defaulting to first journal, but could use logic such as the last selected
+ // journal, etc, once that is in place
+ return jstore.active[0].id;
+ }
+}
/**
* Load a new or existing document into a view model
*/
export function useEditableDocument(
- journals: JournalResponse[],
+ search: SearchV2Store,
+ jstore: JournalsStore,
documentId?: string,
) {
const [document, setDocument] = React.useState(null);
@@ -31,9 +55,7 @@ export function useEditableDocument(
setDocument(
new EditableDocument(client, {
content: "",
- // todo: defaulting to first journal, but could use logic such as the last selected
- // journal, etc, once that is in place
- journalId: journals[0].id,
+ journalId: defaultJournal(search.selectedJournals, jstore),
}),
);
}
@@ -51,7 +73,6 @@ export function useEditableDocument(
}, [documentId]);
return {
- journals,
document,
loadingError: loadingError,
};