diff --git a/pages/integrations/xdd/feedback/@sourceTextID/+Page.client.ts b/pages/integrations/xdd/feedback/@sourceTextID/+Page.client.ts index 90293c4f..9f4d91dc 100644 --- a/pages/integrations/xdd/feedback/@sourceTextID/+Page.client.ts +++ b/pages/integrations/xdd/feedback/@sourceTextID/+Page.client.ts @@ -1,5 +1,5 @@ -import h from "@macrostrat/hyper"; -import { ContentPage } from "~/layouts"; +import h from "./lib/feedback.module.sass"; +import { ContentPage, FullscreenPage } from "~/layouts"; import { PageBreadcrumbs } from "~/components"; import { usePageContext } from "vike-react/usePageContext"; import { enhanceData } from "../../extractions/lib"; @@ -11,7 +11,9 @@ import { import { FeedbackComponent } from "./lib"; import { Intent, NonIdealState, OverlaysProvider } from "@blueprintjs/core"; import { + Box, ErrorBoundary, + FlexCol, FlexRow, Pagination, Spacer, @@ -26,14 +28,16 @@ import { AuthStatus } from "@macrostrat/auth-components"; export function Page() { return h( OverlaysProvider, - h(ContentPage, [ - h(PageBreadcrumbs), - h(FlexRow, { alignItems: "center" }, [ - h("h1", "Feedback"), - h(Spacer), - h(AuthStatus), + h(FullscreenPage, [ + h("div.feedback-main", [ + h(PageBreadcrumbs), + h(FlexRow, { alignItems: "center" }, [ + h("h1", "Feedback"), + h(Spacer), + h(AuthStatus), + ]), + h(ExtractionIndex), ]), - h(ExtractionIndex), ]) ); } @@ -67,7 +71,7 @@ function MultiFeedbackInterface({ data, models, entityTypes }) { const currentData = data[ix]; const count = data.length; - return h("div.feedback", [ + return h("div.feedback-interface", [ h.if(data.length > 1)([ h(NonIdealState, { icon: "warning-sign", diff --git a/pages/integrations/xdd/feedback/@sourceTextID/lib/edit-state.ts b/pages/integrations/xdd/feedback/@sourceTextID/lib/edit-state.ts index 7d58538d..1364cfba 100644 --- a/pages/integrations/xdd/feedback/@sourceTextID/lib/edit-state.ts +++ b/pages/integrations/xdd/feedback/@sourceTextID/lib/edit-state.ts @@ -45,6 +45,7 @@ type TreeAction = | { type: "create-node"; payload: TextRange } | { type: "select-entity-type"; payload: EntityType } | { type: "toggle-entity-type-selector"; payload?: boolean | null } + | { type: "deselect" } | { type: "reset" }; export type TreeDispatch = Dispatch; @@ -232,6 +233,8 @@ function treeReducer(state: TreeState, action: TreeAction) { selectedEntityType: action.payload, }; } + case "deselect": + return { ...state, selectedNodes: [] }; case "reset": return { ...state, diff --git a/pages/integrations/xdd/feedback/@sourceTextID/lib/feedback.module.sass b/pages/integrations/xdd/feedback/@sourceTextID/lib/feedback.module.sass index 95adcbed..61c6eac0 100644 --- a/pages/integrations/xdd/feedback/@sourceTextID/lib/feedback.module.sass +++ b/pages/integrations/xdd/feedback/@sourceTextID/lib/feedback.module.sass @@ -14,7 +14,6 @@ .entity-panel position: relative - padding: 1em .control-panel max-width: 15em @@ -23,3 +22,31 @@ right: 1em padding: 0.2em 0.5em + +.feedback-main + display: flex + flex-direction: column + max-width: 70em + margin: 0 auto + position: relative + max-height: 100% + +.feedback-interface + display: flex + flex-direction: column + flex: 1 + min-height: 100px + + +.entity-panel + flex: 1 + min-height: 100px + padding: 1em + background: var(--panel-secondary-background-color) + border-radius: 4px + // Inset box shadow + box-shadow: 0 0 0 1px var(--panel-border-color) inset + +.selection-tree + margin: -1em 0 + padding: 1em 0 diff --git a/pages/integrations/xdd/feedback/@sourceTextID/lib/index.ts b/pages/integrations/xdd/feedback/@sourceTextID/lib/index.ts index b62fcfcd..cae61521 100644 --- a/pages/integrations/xdd/feedback/@sourceTextID/lib/index.ts +++ b/pages/integrations/xdd/feedback/@sourceTextID/lib/index.ts @@ -10,6 +10,7 @@ import { DataField } from "~/components/unit-details"; import { ButtonGroup, Card } from "@blueprintjs/core"; import { OmniboxSelector } from "./type-selector"; import { CancelButton, SaveButton } from "@macrostrat/ui-components"; +import useElementDimensions from "use-element-dimensions"; function setsAreTheSame(a: Set, b: Set) { if (a.size !== b.size) return false; @@ -37,6 +38,8 @@ export function FeedbackComponent({ const { selectedNodes, tree, selectedEntityType, isSelectingEntityType } = state; + const [{ width, height }, ref] = useElementDimensions(); + return h(TreeDispatchContext.Provider, { value: dispatch }, [ h(FeedbackText, { text, @@ -45,62 +48,73 @@ export function FeedbackComponent({ selectedNodes, }), h(ModelInfo, { data: model }), - h("div.entity-panel", [ - h(Card, { className: "control-panel" }, [ - h( - ButtonGroup, - { - vertical: true, - fill: true, - minimal: true, - alignText: "left", - }, - [ - h( - CancelButton, - { - icon: "trash", - disabled: state.initialTree == state.tree, - onClick() { - dispatch({ type: "reset" }); + h( + "div.entity-panel", + { + ref, + }, + [ + h(Card, { className: "control-panel" }, [ + h( + ButtonGroup, + { + vertical: true, + fill: true, + minimal: true, + alignText: "left", + }, + [ + h( + CancelButton, + { + icon: "trash", + disabled: state.initialTree == state.tree, + onClick() { + dispatch({ type: "reset" }); + }, }, - }, - "Reset" - ), - h( - SaveButton, - { - onClick() { - dispatch({ - type: "save", - tree, - sourceTextID: sourceTextID, - supersedesRunIDs: [runID], - }); + "Reset" + ), + h( + SaveButton, + { + onClick() { + dispatch({ + type: "save", + tree, + sourceTextID: sourceTextID, + supersedesRunIDs: [runID], + }); + }, + disabled: state.initialTree == state.tree, }, - disabled: state.initialTree == state.tree, - }, - "Save" - ), - ] - ), - h(EntityTypeSelector, { - entityTypes, - selected: selectedEntityType, - onChange(payload) { - dispatch({ type: "select-entity-type", payload }); - }, - isOpen: isSelectingEntityType, - setOpen: (isOpen: boolean) => - dispatch({ type: "toggle-entity-type-selector", payload: isOpen }), + "Save" + ), + ] + ), + h(EntityTypeSelector, { + entityTypes, + selected: selectedEntityType, + onChange(payload) { + dispatch({ type: "select-entity-type", payload }); + }, + isOpen: isSelectingEntityType, + setOpen: (isOpen: boolean) => + dispatch({ + type: "toggle-entity-type-selector", + payload: isOpen, + }), + }), + ]), + h(ManagedSelectionTree, { + selectedNodes, + dispatch, + tree, + width, + height, }), - ]), - h(ManagedSelectionTree, { - selectedNodes, - dispatch, - tree, - }), - ]), + ] + ), ]); } @@ -148,7 +162,7 @@ function EntityTypeSelector({ } function ManagedSelectionTree(props) { - const { selectedNodes, dispatch, tree, ...rest } = props; + const { selectedNodes, dispatch, tree, height, width, ...rest } = props; const ref = useRef>(); @@ -170,6 +184,8 @@ function ManagedSelectionTree(props) { return h(Tree, { className: "selection-tree", + height, + width, ref, data: tree, onMove({ dragIds, parentId, index }) {