Skip to content

Commit 27a933c

Browse files
authored
Merge pull request #1628 from ManishMadan2882/main
Smoother transition in settings
2 parents 05319e3 + 71970a0 commit 27a933c

File tree

9 files changed

+418
-317
lines changed

9 files changed

+418
-317
lines changed

frontend/.eslintrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module.exports = {
1818
},
1919
plugins: ['react', 'unused-imports'],
2020
rules: {
21+
'react/prop-types': 'off',
2122
'unused-imports/no-unused-imports': 'error',
2223
'react/react-in-jsx-scope': 'off',
2324
'prettier/prettier': [
Lines changed: 156 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import React, { useState, useEffect } from 'react';
1+
import { useState, useEffect } from 'react';
22

33
interface SkeletonLoaderProps {
44
count?: number;
5-
component?: 'default' | 'analysis' | 'chatbot' | 'logs';
5+
component?:
6+
| 'default'
7+
| 'analysis'
8+
| 'logs'
9+
| 'table'
10+
| 'chatbot'
11+
| 'dropdown';
612
}
713

814
const SkeletonLoader: React.FC<SkeletonLoaderProps> = ({
@@ -32,107 +38,162 @@ const SkeletonLoader: React.FC<SkeletonLoaderProps> = ({
3238
};
3339
}, [count]);
3440

35-
return (
36-
<div className="flex flex-col space-y-4">
37-
{component === 'default' ? (
38-
[...Array(skeletonCount)].map((_, idx) => (
39-
<div
40-
key={idx}
41-
className={`p-6 ${skeletonCount === 1 ? 'w-full' : 'w-60'} dark:bg-raisin-black rounded-3xl animate-pulse`}
42-
>
43-
<div className="space-y-4">
44-
<div>
45-
<div className="h-4 bg-gray-600 rounded mb-2 w-3/4"></div>
46-
<div className="h-4 bg-gray-600 rounded mb-2 w-5/6"></div>
47-
<div className="h-4 bg-gray-600 rounded mb-2 w-1/2"></div>
48-
<div className="h-4 bg-gray-600 rounded mb-2 w-3/4"></div>
49-
<div className="h-4 bg-gray-600 rounded mb-2 w-full"></div>
50-
</div>
51-
<div className="border-t border-gray-600 my-4"></div>
52-
<div>
53-
<div className="h-4 bg-gray-600 rounded mb-2 w-2/3"></div>
54-
<div className="h-4 bg-gray-600 rounded mb-2 w-1/4"></div>
55-
<div className="h-4 bg-gray-600 rounded mb-2 w-full"></div>
56-
</div>
57-
<div className="border-t border-gray-600 my-4"></div>
58-
<div>
59-
<div className="h-4 bg-gray-600 rounded mb-2 w-5/6"></div>
60-
<div className="h-4 bg-gray-600 rounded mb-2 w-1/3"></div>
61-
<div className="h-4 bg-gray-600 rounded mb-2 w-2/3"></div>
62-
<div className="h-4 bg-gray-600 rounded mb-2 w-full"></div>
63-
</div>
64-
<div className="border-t border-gray-600 my-4"></div>
65-
<div className="h-4 bg-gray-600 rounded w-3/4 mb-2"></div>
66-
<div className="h-4 bg-gray-600 rounded w-5/6 mb-2"></div>
41+
const renderTable = () => (
42+
<>
43+
{[...Array(4)].map((_, idx) => (
44+
<tr key={idx} className="animate-pulse">
45+
<td className="py-4 px-4 w-[45%]">
46+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full"></div>
47+
</td>
48+
<td className="py-4 px-4 w-[20%]">
49+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full"></div>
50+
</td>
51+
<td className="py-4 px-4 w-[25%]">
52+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full"></div>
53+
</td>
54+
<td className="py-4 px-4 w-[10%]">
55+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full"></div>
56+
</td>
57+
</tr>
58+
))}
59+
</>
60+
);
61+
62+
const renderChatbot = () => (
63+
<>
64+
{[...Array(4)].map((_, idx) => (
65+
<tr key={idx} className="animate-pulse">
66+
<td className="p-2">
67+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-3/4 mx-auto"></div>
68+
</td>
69+
<td className="p-2">
70+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full mx-auto"></div>
71+
</td>
72+
<td className="p-2">
73+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full mx-auto"></div>
74+
</td>
75+
<td className="p-2">
76+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-8 mx-auto"></div>
77+
</td>
78+
</tr>
79+
))}
80+
</>
81+
);
82+
83+
const renderDropdown = () => (
84+
<div className="animate-pulse">
85+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-24 mb-2"></div>
86+
<div className="w-[360px] h-14 bg-gray-300 dark:bg-gray-600 rounded-3xl flex items-center justify-between px-4">
87+
<div className="h-3 bg-gray-400 dark:bg-gray-700 rounded w-24"></div>
88+
<div className="h-3 w-3 bg-gray-400 dark:bg-gray-700 rounded"></div>
89+
</div>
90+
</div>
91+
);
92+
93+
const renderLogs = () => (
94+
<div className="animate-pulse space-y-px">
95+
{[...Array(8)].map((_, idx) => (
96+
<div
97+
key={idx}
98+
className="flex items-start p-2 hover:bg-[#F9F9F9] hover:dark:bg-dark-charcoal"
99+
>
100+
<div className="flex items-center gap-2">
101+
<div className="w-3 h-3 bg-gray-300 dark:bg-gray-600 rounded-sm"></div>
102+
<div className="flex flex-row items-center gap-2">
103+
<div className="h-3 bg-gray-300 dark:bg-gray-600 rounded w-20"></div>
104+
<div className="h-3 bg-gray-300 dark:bg-gray-600 rounded w-14 bg-opacity-80"></div>
105+
<div className="h-3 bg-gray-300 dark:bg-gray-600 rounded w-40"></div>
67106
</div>
68107
</div>
69-
))
70-
) : component === 'analysis' ? (
71-
[...Array(skeletonCount)].map((_, idx) => (
72-
<div
73-
key={idx}
74-
className="p-6 w-full dark:bg-raisin-black rounded-3xl animate-pulse"
75-
>
76-
<div className="space-y-6">
77-
<div className="space-y-2">
78-
<div className="h-4 bg-gray-600 rounded w-1/3 mb-4"></div>
79-
<div className="grid grid-cols-6 gap-2 items-end">
80-
<div className="h-32 bg-gray-600 rounded"></div>
81-
<div className="h-24 bg-gray-600 rounded"></div>
82-
<div className="h-40 bg-gray-600 rounded"></div>
83-
<div className="h-28 bg-gray-600 rounded"></div>
84-
<div className="h-36 bg-gray-600 rounded"></div>
85-
<div className="h-20 bg-gray-600 rounded"></div>
86-
</div>
87-
</div>
88-
<div className="space-y-2">
89-
<div className="h-4 bg-gray-600 rounded w-1/4 mb-4"></div>
90-
<div className="h-32 bg-gray-600 rounded"></div>
91-
</div>
92-
<div className="grid grid-cols-2 gap-4">
93-
<div className="h-4 bg-gray-600 rounded w-full"></div>
94-
<div className="h-4 bg-gray-600 rounded w-full"></div>
95-
</div>
108+
</div>
109+
))}
110+
</div>
111+
);
112+
113+
const renderDefault = () => (
114+
<>
115+
{[...Array(skeletonCount)].map((_, idx) => (
116+
<div
117+
key={idx}
118+
className={`p-6 ${
119+
skeletonCount === 1 ? 'w-full' : 'w-60'
120+
} dark:bg-raisin-black rounded-3xl animate-pulse`}
121+
>
122+
<div className="space-y-4">
123+
<div>
124+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-3/4"></div>
125+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-5/6"></div>
126+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-1/2"></div>
127+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-3/4"></div>
128+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-full"></div>
96129
</div>
97-
</div>
98-
))
99-
) : component === 'chatbot' ? (
100-
<div className="space-y-2 p-6 w-full dark:bg-raisin-black rounded-3xl animate-pulse">
101-
<div className="grid grid-cols-4 gap-2 p-2">
102-
<div className="h-4 bg-gray-600 rounded w-full"></div>
103-
<div className="h-4 bg-gray-600 rounded w-full"></div>
104-
<div className="h-4 bg-gray-600 rounded w-full"></div>
105-
<div className="h-4 bg-gray-600 rounded w-full"></div>
106-
</div>
107-
<div className="border-t border-gray-600 my-2"></div>
108-
109-
{[...Array(skeletonCount * 6)].map((_, idx) => (
110-
<div key={idx} className="grid grid-cols-4 gap-2 p-2 space-x-2">
111-
<div className="h-4 bg-gray-500 rounded w-full"></div>
112-
<div className="h-4 bg-gray-500 rounded w-full"></div>
113-
<div className="h-4 bg-gray-500 rounded w-full"></div>
114-
<div className="h-4 bg-gray-500 rounded w-full"></div>
130+
<div className="border-t border-gray-400 dark:border-gray-700 my-4"></div>
131+
<div>
132+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-2/3"></div>
133+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-1/4"></div>
134+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-full"></div>
135+
</div>
136+
<div className="border-t border-gray-400 dark:border-gray-700 my-4"></div>
137+
<div>
138+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-5/6"></div>
139+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-1/3"></div>
140+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-2/3"></div>
141+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded mb-2 w-full"></div>
115142
</div>
116-
))}
143+
<div className="border-t border-gray-400 dark:border-gray-700 my-4"></div>
144+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-3/4 mb-2"></div>
145+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-5/6 mb-2"></div>
146+
</div>
117147
</div>
118-
) : (
119-
[...Array(skeletonCount)].map((_, idx) => (
120-
<div
121-
key={idx}
122-
className="p-6 w-full dark:bg-raisin-black rounded-3xl animate-pulse"
123-
>
124-
<div className="space-y-4">
125-
<div className="h-4 bg-gray-600 rounded w-1/2"></div>
126-
<div className="h-4 bg-gray-600 rounded w-5/6"></div>
127-
<div className="h-4 bg-gray-600 rounded w-3/4"></div>
128-
<div className="h-4 bg-gray-600 rounded w-2/3"></div>
129-
<div className="h-4 bg-gray-600 rounded w-1/4"></div>
148+
))}
149+
</>
150+
);
151+
152+
const renderAnalysis = () => (
153+
<>
154+
{[...Array(skeletonCount)].map((_, idx) => (
155+
<div
156+
key={idx}
157+
className="p-6 w-full dark:bg-raisin-black rounded-3xl animate-pulse"
158+
>
159+
<div className="space-y-6">
160+
<div className="space-y-2">
161+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-1/3 mb-4"></div>
162+
<div className="grid grid-cols-6 gap-2 items-end">
163+
<div className="h-32 bg-gray-300 dark:bg-gray-600 rounded"></div>
164+
<div className="h-24 bg-gray-300 dark:bg-gray-600 rounded"></div>
165+
<div className="h-40 bg-gray-300 dark:bg-gray-600 rounded"></div>
166+
<div className="h-28 bg-gray-300 dark:bg-gray-600 rounded"></div>
167+
<div className="h-36 bg-gray-300 dark:bg-gray-600 rounded"></div>
168+
<div className="h-20 bg-gray-300 dark:bg-gray-600 rounded"></div>
169+
</div>
170+
</div>
171+
<div className="space-y-2">
172+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-1/4 mb-4"></div>
173+
<div className="h-32 bg-gray-300 dark:bg-gray-600 rounded"></div>
174+
</div>
175+
<div className="grid grid-cols-2 gap-4">
176+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full"></div>
177+
<div className="h-4 bg-gray-300 dark:bg-gray-600 rounded w-full"></div>
130178
</div>
131179
</div>
132-
))
133-
)}
134-
</div>
180+
</div>
181+
))}
182+
</>
135183
);
184+
185+
const componentMap = {
186+
table: renderTable,
187+
chatbot: renderChatbot,
188+
dropdown: renderDropdown,
189+
logs: renderLogs,
190+
default: renderDefault,
191+
analysis: renderAnalysis,
192+
};
193+
194+
const render = componentMap[component] || componentMap.default;
195+
196+
return <>{render()}</>;
136197
};
137198

138199
export default SkeletonLoader;

frontend/src/conversation/ConversationBubble.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,17 @@ const ConversationBubble = forwardRef<
359359
</SyntaxHighlighter>
360360
<div
361361
className={`absolute right-3 top-3 lg:invisible
362-
${type !== 'ERROR' ? 'group-hover:lg:visible' : ''} `}
362+
${type !== 'ERROR' ? 'group-hover:lg:visible' : ''} `}
363363
>
364364
<CopyButton
365365
text={String(children).replace(/\n$/, '')}
366366
/>
367367
</div>
368368
</div>
369369
) : (
370-
<code className="whitespace-pre-line">{children}</code>
370+
<code className="whitespace-pre-line rounded-[6px] bg-gray-200 px-[8px] py-[4px] text-xs font-normal dark:bg-independence dark:text-bright-gray">
371+
{children}
372+
</code>
371373
);
372374
},
373375
ul({ children }) {
@@ -390,33 +392,33 @@ const ConversationBubble = forwardRef<
390392
},
391393
table({ children }) {
392394
return (
393-
<div className="relative overflow-x-auto rounded-lg border">
394-
<table className="w-full text-left text-sm text-gray-700">
395+
<div className="relative overflow-x-auto rounded-lg border border-silver/40 dark:border-silver/40">
396+
<table className="w-full text-left text-gray-700 dark:text-bright-gray">
395397
{children}
396398
</table>
397399
</div>
398400
);
399401
},
400402
thead({ children }) {
401403
return (
402-
<thead className="text-xs uppercase text-gray-900 [&>.table-row]:bg-gray-50">
404+
<thead className="text-xs uppercase text-gray-900 dark:text-bright-gray bg-gray-50 dark:bg-[#26272E]/50">
403405
{children}
404406
</thead>
405407
);
406408
},
407409
tr({ children }) {
408410
return (
409-
<tr className="table-row border-b odd:bg-white even:bg-gray-50">
411+
<tr className="border-b border-gray-200 dark:border-silver/40 odd:bg-white dark:odd:bg-[#26272E] even:bg-gray-50 dark:even:bg-[#26272E]/50">
410412
{children}
411413
</tr>
412414
);
413415
},
414-
td({ children }) {
415-
return <td className="px-6 py-3">{children}</td>;
416-
},
417416
th({ children }) {
418417
return <th className="px-6 py-3">{children}</th>;
419418
},
419+
td({ children }) {
420+
return <td className="px-6 py-3">{children}</td>;
421+
},
420422
}}
421423
>
422424
{preprocessLaTeX(message)}

frontend/src/hooks/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,23 @@ export function useDarkTheme() {
112112

113113
return [isDarkTheme, toggleTheme, componentMounted] as const;
114114
}
115+
116+
export function useLoaderState(
117+
initialState = false,
118+
delay = 250,
119+
): [boolean, (value: boolean) => void] {
120+
const [state, setState] = useState<boolean>(initialState);
121+
122+
const setLoaderState = (value: boolean) => {
123+
if (value) {
124+
setState(true);
125+
} else {
126+
// Only add delay when changing from true to false
127+
setTimeout(() => {
128+
setState(false);
129+
}, delay);
130+
}
131+
};
132+
133+
return [state, setLoaderState];
134+
}

0 commit comments

Comments
 (0)