refactor: unify AI capabilities and workspace integration
This commit is contained in:
+42
-46
@@ -18,20 +18,16 @@ import { AlphaPage } from "./pages/AlphaPage";
|
||||
import { JobPanel } from "./components/JobPanel";
|
||||
import { BacktestPage } from "./backtests/BacktestPage";
|
||||
import { ChatPanel } from "./ai/ChatPanel";
|
||||
import type { PageContext, UIAction } from "./ai/types";
|
||||
import { actionDestination, pageFromHash } from "./ai/workspace";
|
||||
import type { WorkspacePage } from "./ai/workspace";
|
||||
import type { PageContext, Resource, UIAction } from "./ai/types";
|
||||
|
||||
export default function App() {
|
||||
const [authenticated, setAuthenticated] = useState<boolean | null>(null);
|
||||
const [account, setAccount] = useState<Account | null>(null);
|
||||
const [jobs, setJobs] = useState<Job[]>([]);
|
||||
const [page, setPage] = useState(
|
||||
location.hash === "#backtests"
|
||||
? "backtests"
|
||||
: location.hash === "#datasets"
|
||||
? "datasets"
|
||||
: location.hash === "#account"
|
||||
? "account"
|
||||
: "alphas",
|
||||
const [page, setPage] = useState<WorkspacePage>(() =>
|
||||
pageFromHash(location.hash),
|
||||
);
|
||||
const [visitedBacktests, setVisitedBacktests] = useState(
|
||||
page === "backtests",
|
||||
@@ -42,6 +38,15 @@ export default function App() {
|
||||
const [catalogModal, setCatalogModal] = useState(false);
|
||||
const [showJobs, setShowJobs] = useState(false);
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
const [resourceVersions, setResourceVersions] = useState<
|
||||
Record<Resource, number>
|
||||
>({
|
||||
alphas: 0,
|
||||
datasets: 0,
|
||||
backtests: 0,
|
||||
jobs: 0,
|
||||
account: 0,
|
||||
});
|
||||
const [pollError, setPollError] = useState("");
|
||||
const [chatOpen, setChatOpen] = useState(false);
|
||||
const [chatWidth, setChatWidth] = useState(420);
|
||||
@@ -104,16 +109,7 @@ export default function App() {
|
||||
setShowJobs(false);
|
||||
};
|
||||
window.addEventListener("session-expired", expired);
|
||||
const hash = () =>
|
||||
setPage(
|
||||
location.hash === "#backtests"
|
||||
? "backtests"
|
||||
: location.hash === "#datasets"
|
||||
? "datasets"
|
||||
: location.hash === "#account"
|
||||
? "account"
|
||||
: "alphas",
|
||||
);
|
||||
const hash = () => setPage(pageFromHash(location.hash));
|
||||
window.addEventListener("hashchange", hash);
|
||||
return () => {
|
||||
window.removeEventListener("session-expired", expired);
|
||||
@@ -145,31 +141,31 @@ export default function App() {
|
||||
void refresh();
|
||||
setRefreshKey((k) => k + 1);
|
||||
};
|
||||
const aiChanged = (resources: Resource[]) => {
|
||||
if (resources.includes("jobs") || resources.includes("account"))
|
||||
void refresh();
|
||||
setResourceVersions((old) => {
|
||||
const next = { ...old };
|
||||
for (const resource of resources)
|
||||
if (Object.hasOwn(next, resource)) next[resource] += 1;
|
||||
return next;
|
||||
});
|
||||
};
|
||||
const taskCreated = () => {
|
||||
actionDone();
|
||||
setShowJobs(true);
|
||||
};
|
||||
const changePage = (next: string) => {
|
||||
const changePage = (next: WorkspacePage) => {
|
||||
location.hash = next;
|
||||
setPage(next);
|
||||
};
|
||||
const handleAction = (action: UIAction) => {
|
||||
if (action.type === "open_conversation") {
|
||||
setChatOpen(true);
|
||||
} else {
|
||||
focusBusiness();
|
||||
if (action.type === "open_research_input") {
|
||||
setChatOpen(false);
|
||||
changePage("datasets");
|
||||
} else {
|
||||
changePage(
|
||||
action.type === "open_backtest" ||
|
||||
action.type === "open_backtest_preview"
|
||||
? "backtests"
|
||||
: "alphas",
|
||||
);
|
||||
}
|
||||
}
|
||||
const destination = actionDestination(action);
|
||||
if (!destination) return;
|
||||
if (destination.chat === "open") setChatOpen(true);
|
||||
else if (destination.chat === "close") setChatOpen(false);
|
||||
else focusBusiness();
|
||||
if (destination.page) changePage(destination.page);
|
||||
setAIAction(action);
|
||||
};
|
||||
const logout = async () => {
|
||||
@@ -330,7 +326,7 @@ export default function App() {
|
||||
account={account}
|
||||
jobs={jobs}
|
||||
active={page === "datasets"}
|
||||
version={`${refreshKey}:${completedVersion}`}
|
||||
version={`${refreshKey}:${resourceVersions.datasets}:${completedVersion}`}
|
||||
suspended={showJobs || chatOpen}
|
||||
onTask={taskCreated}
|
||||
onModal={setCatalogModal}
|
||||
@@ -342,7 +338,7 @@ export default function App() {
|
||||
onAction={handleAction}
|
||||
taskPanelOpen={showJobs}
|
||||
account={account}
|
||||
version={`${refreshKey}:${completedVersion}`}
|
||||
version={`${refreshKey}:${resourceVersions.alphas}:${completedVersion}`}
|
||||
onTask={taskCreated}
|
||||
onAccount={() => changePage("account")}
|
||||
active={page === "alphas"}
|
||||
@@ -363,6 +359,7 @@ export default function App() {
|
||||
<div className="backtest-page-view" hidden={page !== "backtests"}>
|
||||
{visitedBacktests && (
|
||||
<BacktestPage
|
||||
version={resourceVersions.backtests}
|
||||
active={page === "backtests"}
|
||||
suspended={showJobs || (viewport < 1440 && chatOpen)}
|
||||
chatOffset={chatOffset}
|
||||
@@ -414,13 +411,12 @@ export default function App() {
|
||||
onWidth={setChatWidth}
|
||||
onClose={() => setChatOpen(false)}
|
||||
context={
|
||||
page === "alphas"
|
||||
? alphaContext
|
||||
: page === "backtests"
|
||||
? backtestContext
|
||||
: page === "datasets"
|
||||
? datasetContext
|
||||
: { page: "account" }
|
||||
{
|
||||
alphas: alphaContext,
|
||||
datasets: datasetContext,
|
||||
backtests: backtestContext,
|
||||
account: { page: "account" as const },
|
||||
}[page]
|
||||
}
|
||||
timezone={account?.timezone}
|
||||
onSettings={() => {
|
||||
@@ -432,7 +428,7 @@ export default function App() {
|
||||
?.scrollIntoView({ block: "start" }),
|
||||
);
|
||||
}}
|
||||
onChanged={actionDone}
|
||||
onChanged={aiChanged}
|
||||
onAction={handleAction}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user