Skip to content

Commit cacc66b

Browse files
authored
Merge pull request #1319 from BudEcosystem/bugfix/agent-new
Bugfix/agent new
2 parents 2d298a0 + 9498ff3 commit cacc66b

File tree

8 files changed

+139
-41
lines changed

8 files changed

+139
-41
lines changed

services/budadmin/src/components/auth/contactAdmin.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,11 @@ const ContactAdmin = ({ onSubmit }: ContactAdminKeyProps) => {
165165
}}
166166
>
167167
<Text_12_400_EEEEEE className="text-[#EC7575]">
168-
{authError.includes("Cannot read properties")
169-
? "Something went wrong, please try again later."
170-
: authError}
168+
{typeof window !== "undefined" && !navigator.onLine
169+
? "No internet connection"
170+
: authError.includes("Cannot read properties")
171+
? "Something went wrong, please try again later."
172+
: authError}
171173
</Text_12_400_EEEEEE>
172174
</motion.div>
173175
)}

services/budadmin/src/components/auth/login.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,11 @@ const LoginPage = ({ onSubmit }: LoginPageModalProps) => {
293293
}}
294294
>
295295
<Text_12_400_EEEEEE className="text-[#EC7575]">
296-
{authError.includes("Cannot read properties")
297-
? "Something went wrong, please try again later."
298-
: authError}
296+
{typeof window !== "undefined" && !navigator.onLine
297+
? "No internet connection"
298+
: authError.includes("Cannot read properties")
299+
? "Something went wrong, please try again later."
300+
: authError}
299301
</Text_12_400_EEEEEE>
300302
</motion.div>
301303
)}

services/budadmin/src/components/auth/resetPassword.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,11 @@ const ResetPasswordPage = ({ onSubmit }: ResetPasswordProps) => {
282282
}}
283283
>
284284
<Text_12_400_EEEEEE className="text-[#EC7575]">
285-
{authError.includes("Cannot read properties")
286-
? "Something went wrong, please try again later."
287-
: authError}
285+
{typeof window !== "undefined" && !navigator.onLine
286+
? "No internet connection"
287+
: authError.includes("Cannot read properties")
288+
? "Something went wrong, please try again later."
289+
: authError}
288290
</Text_12_400_EEEEEE>
289291
</motion.div>
290292
)}

services/budadmin/src/components/ui/bud/deploymentDrawer/DeployModelSelect.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Text_12_300_EEEEEE, Text_12_600_EEEEEE } from "../../text";
44
import { ModelListCard } from "./ModelListCard";
55
import { Tag } from "../dataEntry/TagsInput";
66
import { useDrawer } from "src/hooks/useDrawer";
7-
import { Checkbox } from "antd";
7+
import { Checkbox, Spin } from "antd";
88

99
function DeployModelSelect({
1010
multiSelect,
@@ -22,7 +22,8 @@ function DeployModelSelect({
2222
hideSelect,
2323
emptyComponent = <Text_12_300_EEEEEE className="pl-5">
2424
To add new models for the provider, click the &quot;+Cloud Model&quot; button
25-
</Text_12_300_EEEEEE>
25+
</Text_12_300_EEEEEE>,
26+
isLoadingMore,
2627
}: {
2728
multiSelect?: boolean;
2829
multiSelectedModels?: Model[];
@@ -38,6 +39,7 @@ function DeployModelSelect({
3839
children: React.ReactNode;
3940
hideSelect?: boolean;
4041
emptyComponent?: React.ReactNode;
42+
isLoadingMore?: boolean;
4143
}) {
4244
const [selectAllModels, setSelectAllModels] = useState<boolean>(false);
4345

@@ -123,6 +125,11 @@ function DeployModelSelect({
123125
)}
124126
</div>
125127
))}
128+
{isLoadingMore && (
129+
<div className="flex justify-center items-center py-4">
130+
<Spin size="small" />
131+
</div>
132+
)}
126133
</>
127134
) : (
128135
<div className="flex justify-center items-center min-h-[4rem]">

services/budadmin/src/flows/AddModel/Cloud/ModelList.tsx

Lines changed: 93 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,23 @@ import { BudDrawerLayout } from "@/components/ui/bud/dataEntry/BudDrawerLayout";
55
import { BudForm } from "@/components/ui/bud/dataEntry/BudForm";
66
import DeployModelSelect from "@/components/ui/bud/deploymentDrawer/DeployModelSelect";
77
import ModelFilter from "@/components/ui/bud/deploymentDrawer/ModelFilter";
8-
import React, { useContext, useEffect } from "react";
8+
import React, { useContext, useEffect, useRef, useCallback } from "react";
99
import { useDrawer } from "src/hooks/useDrawer";
1010
import { useModels } from "src/hooks/useModels";
1111
import { useDeployModel } from "src/stores/useDeployModel";
1212

13+
const PAGE_SIZE = 50;
14+
1315
export default function ModelList() {
1416
const { openDrawerWithStep } = useDrawer();
1517

16-
const [page, setPage] = React.useState(1);
17-
const [limit, setLimit] = React.useState(100);
18+
const pageRef = useRef(1);
1819

1920
const { selectedProvider, modalityType } = useDeployModel();
2021
const [models, setModels] = React.useState([]);
22+
const [hasMore, setHasMore] = React.useState(true);
23+
const [isLoadingMore, setIsLoadingMore] = React.useState(false);
24+
const lastScrollTop = useRef(0);
2125
const { isExpandedViewOpen } = useContext(BudFormContext);
2226

2327
const { loading, fetchModels } = useModels();
@@ -27,36 +31,105 @@ export default function ModelList() {
2731
const { selectedModel, setSelectedModel, currentWorkflow, updateCloudModel } =
2832
useDeployModel();
2933

34+
const getFilterParams = useCallback(() => {
35+
const endpoints =
36+
modalityType?.endpoints && modalityType.endpoints.length > 0
37+
? modalityType.endpoints
38+
: undefined;
39+
const modalities =
40+
!endpoints &&
41+
modalityType?.modalities &&
42+
modalityType.modalities.length > 0
43+
? modalityType.modalities
44+
: undefined;
45+
46+
return {
47+
table_source: "cloud_model" as const,
48+
source: selectedProvider?.type,
49+
modality: modalities,
50+
supported_endpoints: endpoints,
51+
};
52+
}, [
53+
selectedProvider?.type,
54+
modalityType?.modalities,
55+
modalityType?.endpoints,
56+
]);
57+
3058
useEffect(() => {
3159
if (currentWorkflow?.workflow_steps?.model) {
3260
setSelectedModel(currentWorkflow.workflow_steps.model);
3361
}
3462
}, [currentWorkflow]);
3563

3664
useEffect(() => {
37-
const endpoints = modalityType?.endpoints && modalityType.endpoints.length > 0
38-
? modalityType.endpoints
39-
: undefined;
40-
const modalities = !endpoints && modalityType?.modalities && modalityType.modalities.length > 0
41-
? modalityType.modalities
42-
: undefined;
43-
4465
if (!selectedProvider?.type) {
4566
setModels([]);
67+
setHasMore(false);
4668
return;
4769
}
4870

71+
pageRef.current = 1;
72+
setHasMore(true);
73+
4974
fetchModels({
50-
page,
51-
limit,
52-
table_source: "cloud_model",
53-
source: selectedProvider?.type,
54-
modality: modalities,
55-
supported_endpoints: endpoints,
75+
page: 1,
76+
limit: PAGE_SIZE,
77+
...getFilterParams(),
5678
}).then((data) => {
57-
setModels(data);
79+
const items = data || [];
80+
setModels(items);
81+
setHasMore(items.length >= PAGE_SIZE);
5882
});
59-
}, [selectedProvider?.type, modalityType?.modalities, modalityType?.endpoints, page, limit, fetchModels]);
83+
}, [
84+
selectedProvider?.type,
85+
modalityType?.modalities,
86+
modalityType?.endpoints,
87+
fetchModels,
88+
getFilterParams,
89+
]);
90+
91+
const loadMore = useCallback(() => {
92+
if (isLoadingMore || !hasMore || loading) return;
93+
94+
setIsLoadingMore(true);
95+
const nextPage = pageRef.current + 1;
96+
97+
fetchModels({
98+
page: nextPage,
99+
limit: PAGE_SIZE,
100+
...getFilterParams(),
101+
})
102+
.then((data) => {
103+
const items = data || [];
104+
if (items.length > 0) {
105+
setModels((prev) => [...prev, ...items]);
106+
pageRef.current = nextPage;
107+
}
108+
setHasMore(items.length >= PAGE_SIZE);
109+
})
110+
.finally(() => {
111+
setIsLoadingMore(false);
112+
});
113+
}, [isLoadingMore, hasMore, loading, fetchModels, getFilterParams]);
114+
115+
const handleScroll = useCallback(
116+
(e: React.UIEvent<HTMLDivElement>) => {
117+
const target = e.currentTarget;
118+
const { scrollTop, scrollHeight, clientHeight } = target;
119+
120+
if (scrollTop <= lastScrollTop.current) {
121+
lastScrollTop.current = scrollTop;
122+
return;
123+
}
124+
lastScrollTop.current = scrollTop;
125+
126+
const isNearBottom = scrollTop + clientHeight >= scrollHeight - 100;
127+
if (isNearBottom) {
128+
loadMore();
129+
}
130+
},
131+
[loadMore],
132+
);
60133

61134
useEffect(() => {
62135
if (!selectedModel) {
@@ -96,7 +169,7 @@ export default function ModelList() {
96169
}
97170
}}
98171
>
99-
<BudWraperBox>
172+
<BudWraperBox onScroll={handleScroll}>
100173
<BudDrawerLayout>
101174
<DrawerTitleCard
102175
title={`Select a Model from ${selectedProvider?.name}`}
@@ -108,6 +181,7 @@ export default function ModelList() {
108181
setSelectedModel={setSelectedModel}
109182
selectedModel={selectedModel}
110183
hideSeeMore
184+
isLoadingMore={isLoadingMore}
111185
>
112186
<ModelFilter
113187
search={search}

services/budadmin/src/pages/api/requests.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ axiosInstance.defaults.paramsSerializer = {
4747
serialize: serializeParams,
4848
};
4949

50+
let lastNoInternetToast = 0;
51+
let lastSlowNetworkToast = 0;
52+
const NETWORK_TOAST_INTERVAL = 5 * 60 * 1000; // 5 minutes
53+
5054
let Token = null;
5155
export let isRefreshing = false;
5256
export let refreshSubscribers: ((token: string) => void)[] = [];
@@ -70,13 +74,17 @@ if (typeof window !== "undefined") {
7074

7175
axiosInstance.interceptors.request.use(
7276
async (config) => {
73-
// ✅ Check Internet Connection
77+
// ✅ Check Internet Connection (toast throttled to once per 5 minutes)
7478
if (typeof window !== "undefined" && !navigator.onLine) {
75-
errorToast("No internet connection");
79+
const now = Date.now();
80+
if (now - lastNoInternetToast >= NETWORK_TOAST_INTERVAL) {
81+
lastNoInternetToast = now;
82+
errorToast("No internet connection");
83+
}
7684
return Promise.reject(new Error("No internet connection"));
7785
}
7886

79-
// ✅ Optional: Network quality check
87+
// ✅ Optional: Network quality check (toast throttled to once per 5 minutes)
8088
const connection =
8189
(navigator as any).connection ||
8290
(navigator as any)["mozConnection"] ||
@@ -88,8 +96,11 @@ axiosInstance.interceptors.request.use(
8896
["2g", "slow-2g"].includes(effectiveType) || downlink < 0.5;
8997

9098
if (slowConnection) {
91-
errorToast("Network is too slow or throttled");
92-
return Promise.reject(new Error("Poor network connection"));
99+
const now = Date.now();
100+
if (now - lastSlowNetworkToast >= NETWORK_TOAST_INTERVAL) {
101+
lastSlowNetworkToast = now;
102+
errorToast("Network is too slow or throttled");
103+
}
93104
}
94105
}
95106

services/budadmin/src/pages/home/modelRepo/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,14 +400,14 @@ export default function ModelRepo() {
400400
}
401401
}, [filterReset]);
402402

403-
// Initial load
403+
// Initial load - wait for permissions to be ready before fetching data
404404
useEffect(() => {
405-
if (isMounted && hasPermission(PermissionEnum.ModelView)) {
405+
if (isMounted && !loadingUser && hasPermission(PermissionEnum.ModelView)) {
406406
getTasks();
407407
getAuthors();
408408
load(filter, 1, false);
409409
}
410-
}, [isMounted]);
410+
}, [isMounted, loadingUser]);
411411

412412
// Search with debounce
413413
useEffect(() => {

services/budadmin/src/pages/home/projects/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ const Projects = () => {
8181
}
8282
}, [getGlobalProjects, hasPermission, hideLoader, showLoader, setPageSize]);
8383

84-
// Initial load
84+
// Initial load - wait for permissions to be ready before fetching data
8585
useEffect(() => {
86-
if (isMounted) {
86+
if (isMounted && !loadingUser) {
8787
setCurrentPage(1);
8888
load(1, pageSize);
8989
}
90-
}, [isMounted, load, pageSize]);
90+
}, [isMounted, loadingUser, load, pageSize]);
9191

9292
// Search with debounce
9393
useEffect(() => {

0 commit comments

Comments
 (0)