From 3fe6408365a7fdf404e92ff021608433fd58bdf9 Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Tue, 21 Nov 2023 21:30:15 -0600 Subject: [PATCH 1/7] add support for kanban embed and embed fold setting --- src/components/Kanban.tsx | 63 ++- src/components/ResultsTable.tsx | 7 +- src/components/ResultsView.tsx | 879 +++++++++++++++++--------------- 3 files changed, 523 insertions(+), 426 deletions(-) diff --git a/src/components/Kanban.tsx b/src/components/Kanban.tsx index dd60eb1f..d2764e61 100644 --- a/src/components/Kanban.tsx +++ b/src/components/Kanban.tsx @@ -19,6 +19,7 @@ import toCellValue from "../utils/toCellValue"; import extractTag from "roamjs-components/util/extractTag"; import deleteBlock from "roamjs-components/writes/deleteBlock"; import getSubTree from "roamjs-components/util/getSubTree"; +import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid"; const zPriority = z.record(z.number().min(0).max(1)); @@ -30,9 +31,44 @@ const KanbanCard = (card: { $displayKey: string; $getColumnElement: (x: number) => HTMLDivElement | undefined; result: Result; + view: string; + viewValue: string; }) => { const [isDragging, setIsDragging] = useState(false); + const CellEmbed = ({ + uid, + viewValue, + }: { + uid: string; + viewValue: string; + }) => { + console.log("CellEmbed render"); + const title = getPageTitleByPageUid(uid); + const contentRef = useRef(null); + const open = + viewValue === "open" ? true : viewValue === "closed" ? false : null; + + useEffect(() => { + const el = contentRef.current; + if (el) { + window.roamAlphaAPI.ui.components.renderBlock({ + uid, + el, + "open?": open, + }); + } + }, [contentRef]); + return ( +
+
+
+ ); + }; + return ( { @@ -73,12 +109,17 @@ const KanbanCard = (card: { } }} > -
- {toCellValue({ - value: card.result[card.$displayKey], - uid: card.result[`${card.$displayKey}-uid`], - })} -
+ {card.view === "embed" ? ( + + ) : ( +
+ {console.log("toCellValue render")} + {toCellValue({ + value: card.result[card.$displayKey], + uid: card.result[`${card.$displayKey}-uid`], + })} +
+ )}
); @@ -98,12 +139,14 @@ const Kanban = ({ onQuery, resultKeys, parentUid, + views, }: { resultKeys: Column[]; data: Result[]; layout: Record; onQuery: () => void; parentUid: string; + views: { column: string; mode: string; value: string }[]; }) => { const byUid = useMemo( () => Object.fromEntries(data.map((d) => [d.uid, d] as const)), @@ -347,6 +390,12 @@ const Kanban = ({ setOpenedPopoverIndex(null); }; + const viewsByColumn = useMemo( + () => Object.fromEntries(views.map((v) => [v.column, v])), + [views] + ); + const { mode: view, value: viewValue } = viewsByColumn[displayKey] || {}; + return ( <> {showLegend === "Yes" && ( @@ -438,6 +487,8 @@ const Kanban = ({ { +const CellEmbed = ({ uid, viewValue }: { uid: string; viewValue: string }) => { const title = getPageTitleByPageUid(uid); const contentRef = useRef(null); + const open = + viewValue === "open" ? true : viewValue === "closed" ? false : null; useEffect(() => { const el = contentRef.current; if (el) { window.roamAlphaAPI.ui.components.renderBlock({ uid, el, + "open?": open, }); } }, [contentRef]); @@ -335,7 +338,7 @@ const ResultRow = ({ {view === "alias" ? viewValue : cell(key)} ) : view === "embed" ? ( - + ) : ( cell(key) )} diff --git a/src/components/ResultsView.tsx b/src/components/ResultsView.tsx index 7d91a359..b56a9360 100644 --- a/src/components/ResultsView.tsx +++ b/src/components/ResultsView.tsx @@ -40,9 +40,10 @@ import { render as renderSimpleAlert } from "roamjs-components/components/Simple const VIEWS: Record = { link: { value: false }, plain: { value: false }, - embed: { value: false }, + embed: { value: true }, alias: { value: true }, }; +const EMBED_FOLD_VALUES = ["default", "open", "closed"]; type EnglishQueryPart = { text: string; clickId?: string }; @@ -347,8 +348,6 @@ const ResultsView: ResultsViewComponent = ({
setShowMenuIcons(true)} - onMouseOut={() => setShowMenuIcons(false)} > {isEditSearchFilter && (
- { + if (!showInterface) setShowMenuIcons(true); + }} + onMouseLeave={() => { + if (!showInterface) setShowMenuIcons(false); + }} > - {onRefresh && ( - -
- ) : isEditLayout ? ( -
-

- Layout -

-
- {SUPPORTED_LAYOUTS.map((l) => ( -
{ - setLayout({ ...layout, mode: l.id }); - const resultNode = getSubTree({ - key: "results", - parentUid, - }); - const layoutNode = getSubTree({ - key: "layout", - parentUid: resultNode.uid, - }); - setInputSetting({ - key: "mode", - value: l.id, - blockUid: layoutNode.uid, - }); - setIsEditLayout(false); - setMoreMenuOpen(false); - }} - > - - {l.id} -
- ))}
- {settingsById[layoutMode].map((s) => { - const options = - s.options === "columns" - ? columns.map((c) => c.key) - : s.options.slice(); - return ( -
+
{header && (

onRefresh(true)} resultKeys={columns} parentUid={parentUid} + views={views} /> ) : (
From 12cdf5b04604f3037c5bf6ecdc73c5c85495b197 Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Wed, 22 Nov 2023 18:58:23 -0600 Subject: [PATCH 2/7] store localFoldStates --- src/components/Kanban.tsx | 84 +++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/src/components/Kanban.tsx b/src/components/Kanban.tsx index d2764e61..55e7dc4d 100644 --- a/src/components/Kanban.tsx +++ b/src/components/Kanban.tsx @@ -25,15 +25,27 @@ const zPriority = z.record(z.number().min(0).max(1)); type Reprioritize = (args: { uid: string; x: number; y: number }) => void; -const KanbanCard = (card: { - $priority: number; - $reprioritize: Reprioritize; - $displayKey: string; - $getColumnElement: (x: number) => HTMLDivElement | undefined; - result: Result; - view: string; - viewValue: string; -}) => { +type KanbanCardProps = { + card: { + $priority: number; + $reprioritize: Reprioritize; + $displayKey: string; + $getColumnElement: (x: number) => HTMLDivElement | undefined; + result: Result; + view: string; + viewValue: string; + }; + localFoldStates: Map; + setLocalFoldStates: React.Dispatch< + React.SetStateAction> + >; +}; + +const KanbanCard = ({ + card, + localFoldStates, + setLocalFoldStates, +}: KanbanCardProps) => { const [isDragging, setIsDragging] = useState(false); const CellEmbed = ({ @@ -43,11 +55,15 @@ const KanbanCard = (card: { uid: string; viewValue: string; }) => { - console.log("CellEmbed render"); const title = getPageTitleByPageUid(uid); const contentRef = useRef(null); - const open = - viewValue === "open" ? true : viewValue === "closed" ? false : null; + const open = localFoldStates.has(uid) + ? localFoldStates.get(uid) + : viewValue === "open" + ? true + : viewValue === "closed" + ? false + : null; useEffect(() => { const el = contentRef.current; @@ -60,7 +76,27 @@ const KanbanCard = (card: { } }, [contentRef]); return ( -
+
{ + const target = e.target as HTMLElement; + if (!target.classList.contains("rm-caret")) return; + + const kanbanCard = target.closest(".roamjs-kanban-card"); + const uid = kanbanCard?.getAttribute("data-uid"); + if (!uid) return; + + const isOpen = target.classList.contains("rm-caret-open"); + const storedOpenState = !isOpen; + + setLocalFoldStates((prev) => { + const newMap = new Map(prev); + newMap.set(uid, storedOpenState); + return newMap; + }); + }} + > + { + const [localFoldStates, setLocalFoldStates] = useState( + new Map() + ); const byUid = useMemo( () => Object.fromEntries(data.map((d) => [d.uid, d] as const)), [data] @@ -486,14 +525,17 @@ const Kanban = ({ {(cards[col] || [])?.map((d) => ( ))}
From 87be54c43b2d3fe764d6a643f80ef01f5fd8f8a5 Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Wed, 22 Nov 2023 18:58:36 -0600 Subject: [PATCH 3/7] Refactor ResultsView component to include column view options --- src/components/ResultsView.tsx | 129 ++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 51 deletions(-) diff --git a/src/components/ResultsView.tsx b/src/components/ResultsView.tsx index b56a9360..b6ed8466 100644 --- a/src/components/ResultsView.tsx +++ b/src/components/ResultsView.tsx @@ -10,6 +10,7 @@ import { Switch, Intent, Label, + HTMLTable, } from "@blueprintjs/core"; import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; import { Filters } from "roamjs-components/components/Filter"; @@ -344,6 +345,10 @@ const ResultsView: ResultsViewComponent = ({ ); }; const debounceRef = useRef(0); + const showColumnViewOptions = views.some( + (view) => VIEWS[view.mode]?.value === true + ); + return (
) : isEditViews ? ( -
+

Set Column Views

-
- {views.map(({ column, mode, value }, i) => ( - -
- - {column} - - { - onViewChange({ mode: m, column, value }, i); - }} - /> -
- {VIEWS[mode]?.value && mode === "alias" && ( - { - onViewChange( - { mode, column, value: e.target.value }, - i - ); - }} - /> + + + + + Column + + + View + + {showColumnViewOptions && ( + + Options + )} - {VIEWS[mode]?.value && mode === "embed" && ( -
-
- Fold - - - -
+ + + + {views.map(({ column, mode, value }, i) => ( + + {column} + + onViewChange({ mode: m, column, value }, i) } - onItemSelect={(value) => { - onViewChange({ mode, column, value }, i); - }} /> -
- )} -
- ))} -
+ + {showColumnViewOptions && ( + + {mode === "alias" && ( + + onViewChange( + { + mode, + column, + value: e.target.value, + }, + i + ) + } + /> + )} + {mode === "embed" && ( +
+ { + onViewChange( + { mode, column, value }, + i + ); + }} + /> + + + +
+ )} + + )} + + ))} + +
) : ( From 52f4de9b2c8d8c8e63006e0ad3db1bcd5d5fe8c0 Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Wed, 22 Nov 2023 18:58:46 -0600 Subject: [PATCH 4/7] Add drag handle to KanbanCard component --- src/components/Kanban.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/Kanban.tsx b/src/components/Kanban.tsx index 55e7dc4d..29aa8e56 100644 --- a/src/components/Kanban.tsx +++ b/src/components/Kanban.tsx @@ -97,6 +97,9 @@ const KanbanCard = ({ }} >
); }; - return ( { const { x, width } = data.node.getBoundingClientRect(); const el = card.$getColumnElement(x + width / 2); @@ -131,6 +134,7 @@ const KanbanCard = ({ data-uid={card.result.uid} data-priority={card.$priority} onClick={(e) => { + if (card.view === "embed") return; if (isDragging) return; if (e.shiftKey) { openBlockInSidebar(card.result.uid); @@ -148,8 +152,7 @@ const KanbanCard = ({ {card.view === "embed" ? ( ) : ( -
- {console.log("toCellValue render")} +
{toCellValue({ value: card.result[card.$displayKey], uid: card.result[`${card.$displayKey}-uid`], From 1420a1600aa7ff527ec8806fcab23ef990e3cc7b Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Wed, 22 Nov 2023 18:58:58 -0600 Subject: [PATCH 5/7] css update --- src/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 306d599a..526cc0a5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -153,7 +153,7 @@ svg.rs-svg-container { } .roamjs-kanban-container div.react-draggable-dragging.roamjs-kanban-card > div { - transform: rotate(20deg); + transform: rotate(5deg); cursor: grabbing; z-index: 1000; } @@ -182,7 +182,14 @@ svg.rs-svg-container { .roamjs-export-dialog-body .bp3-tab-list { padding: 10px 20px; border-bottom: 1px solid rgba(16,22,26,0.15); -}`); +} +.roamjs-query-column-views .bp3-running-text table th, +.roamjs-query-column-views table.bp3-html-table th, +.roamjs-query-column-views .bp3-running-text table td, +.roamjs-query-column-views table.bp3-html-table td { + vertical-align: initial; +} +`); const isCanvasPage = (title: string) => { const canvasPageFormat = (extensionAPI.settings.get("canvas-page-format") as string) || From 4cd1e3c528123bacc2fe726f6d2c5f566b9ab422 Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Wed, 22 Nov 2023 19:33:56 -0600 Subject: [PATCH 6/7] add min width to Column Views --- src/components/ResultsView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ResultsView.tsx b/src/components/ResultsView.tsx index b6ed8466..1311f7e0 100644 --- a/src/components/ResultsView.tsx +++ b/src/components/ResultsView.tsx @@ -681,7 +681,10 @@ const ResultsView: ResultsViewComponent = ({
) : isEditViews ? ( -
+

Set Column Views