Unverified 提交 6a5efb94 authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Fix stale UI (#2027)

<!-- CURSOR_SUMMARY --> > [!NOTE] > Addresses stale UI by ensuring key data refreshes immediately after user actions and upgrades. > > - **Token usage refresh**: `ChatInput` toggling the token bar now invalidates `TOKEN_COUNT_QUERY_KEY` to recompute percentages > - **Versions refresh after upgrades**: `AppUpgrades` invalidates `['versions', appId]` on successful upgrade > - **Templates loading**: `useTemplates` uses `placeholderData` (replacing `initialData`) to avoid sticky outdated results > - **Null safety**: `hub.tsx` guards template lookup with optional chaining when passing to `CreateAppDialog` > - **E2E**: `supabase_branch.spec.ts` re-opens the token bar before assertions to validate refreshed counts > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 06c5b8796906ae1dfdf8afda36caa62870781564. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixes stale UI by refreshing queries when toggling the token bar and after app upgrades, and by using placeholder data for templates. Users now see up-to-date token counts, versions, and templates. - **Bug Fixes** - Token bar toggle now invalidates the token count query to refresh percentages after branch changes. - App upgrades invalidate the versions query so the latest status shows immediately. - Templates query uses placeholderData instead of initialData to avoid sticky, outdated results. - E2E test updated to reopen the token bar and assert refreshed token counts. - Create app dialog guards against undefined templates to prevent a null error. <sup>Written for commit 06c5b8796906ae1dfdf8afda36caa62870781564. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: 's avatarclaude[bot] <209825114+claude[bot]@users.noreply.github.com>
上级 64b36f4e
......@@ -13,6 +13,8 @@ testSkipIfWindows("supabase branch selection works", async ({ po }) => {
await po.page.getByTestId("token-bar-toggle").click();
// The default branch has a small context.
await expect(po.page.getByTestId("token-bar")).toContainText("6% of 128K");
// We hide the token bar so we re-open it later to refresh the token count.
await po.page.getByTestId("token-bar-toggle").click();
await po.getTitleBarAppNameButton().click();
await po.page.getByTestId("supabase-branch-select").click();
......@@ -21,5 +23,6 @@ testSkipIfWindows("supabase branch selection works", async ({ po }) => {
await po.clickBackButton();
// The test branch has a large context (200k tokens) so it'll hit the 100% limit.
// This is to make sure we're connecting to the right supabase project for the branch.
await po.page.getByTestId("token-bar-toggle").click();
await expect(po.page.getByTestId("token-bar")).toContainText("100% of 128K");
});
......@@ -46,6 +46,7 @@ export function AppUpgrades({ appId }: { appId: number | null }) {
// query to show the new status.
queryClient.invalidateQueries({ queryKey: ["is-capacitor", appId] });
}
queryClient.invalidateQueries({ queryKey: ["versions", appId] });
},
});
......
......@@ -78,6 +78,8 @@ import { LexicalChatInput } from "./LexicalChatInput";
import { useChatModeToggle } from "@/hooks/useChatModeToggle";
import { VisualEditingChangesDialog } from "@/components/preview_panel/VisualEditingChangesDialog";
import { useUserBudgetInfo } from "@/hooks/useUserBudgetInfo";
import { useQueryClient } from "@tanstack/react-query";
import { TOKEN_COUNT_QUERY_KEY } from "@/hooks/useCountTokens";
const showTokenBarAtom = atom(false);
......@@ -96,10 +98,11 @@ export function ChatInput({ chatId }: { chatId?: number }) {
const setMessagesById = useSetAtom(chatMessagesByIdAtom);
const setIsPreviewOpen = useSetAtom(isPreviewOpenAtom);
const [showTokenBar, setShowTokenBar] = useAtom(showTokenBarAtom);
const toggleShowTokenBar = useCallback(
() => setShowTokenBar((prev) => !prev),
[setShowTokenBar],
);
const queryClient = useQueryClient();
const toggleShowTokenBar = useCallback(() => {
setShowTokenBar((prev) => !prev);
queryClient.invalidateQueries({ queryKey: TOKEN_COUNT_QUERY_KEY });
}, [setShowTokenBar, queryClient]);
const [selectedComponents, setSelectedComponents] = useAtom(
selectedComponentsPreviewAtom,
);
......
......@@ -9,7 +9,7 @@ export function useTemplates() {
const ipcClient = IpcClient.getInstance();
return ipcClient.getTemplates();
},
initialData: localTemplatesData,
placeholderData: localTemplatesData,
meta: {
showErrorToast: true,
},
......
......@@ -96,7 +96,7 @@ const HubPage: React.FC = () => {
<CreateAppDialog
open={isCreateDialogOpen}
onOpenChange={setIsCreateDialogOpen}
template={templates.find((t) => t.id === settings?.selectedTemplateId)}
template={templates?.find((t) => t.id === settings?.selectedTemplateId)}
/>
</div>
);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论