Skip to content

Commit 97cea81

Browse files
author
Jicheng Lu
committed
refine page loading
1 parent 4930c3c commit 97cea81

File tree

31 files changed

+578
-447
lines changed

31 files changed

+578
-447
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script>
2+
import { onMount, onDestroy } from 'svelte';
3+
import { globalErrorStore, loaderStore } from '$lib/helpers/store';
4+
5+
/** @type {boolean} */
6+
export let isLoading = false;
7+
export let hasError = false;
8+
9+
/** @type {any} */
10+
let loaderUnsubscriber;
11+
/** @type {any} */
12+
let errorUnsubscriber;
13+
14+
onMount(() => {
15+
window?.speechSynthesis?.cancel();
16+
loaderUnsubscriber = loaderStore.subscribe(value => {
17+
isLoading = value;
18+
});
19+
20+
errorUnsubscriber = globalErrorStore.subscribe(value => {
21+
hasError = value;
22+
});
23+
});
24+
25+
onDestroy(() => {
26+
loaderUnsubscriber?.();
27+
errorUnsubscriber?.();
28+
});
29+
</script>

src/lib/helpers/http.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const retryQueue = {
3131
/** @param {{config: import('axios').InternalAxiosRequestConfig, resolve: (value: any) => void, reject: (reason?: any) => void}} item */
3232
enqueue(item) {
3333
this.queue.push(item);
34-
34+
console.log('queue', this.queue.length);
3535
if (!this.isRefreshingToken) {
3636
const user = getUserStore();
3737
if (!isTokenExired(user.expires)) {
@@ -130,7 +130,7 @@ axios.interceptors.response.use(
130130
loaderStore.set(false);
131131
const originalRequest = error?.config || {};
132132
const user = getUserStore();
133-
console.log("renew token count.", user.renew_token_count);
133+
134134
if (!user?.token || user.renew_token_count >= retryQueue.maxRenewTokenCount) {
135135
retryQueue.queue = [];
136136
redirectToLogin();
@@ -209,7 +209,6 @@ function skipLoader(config) {
209209
/** @type {RegExp[]} */
210210
const getRegexes = [
211211
new RegExp('http(s*)://(.*?)/plugin/menu', 'g'),
212-
new RegExp('http(s*)://(.*?)/settings', 'g'),
213212
new RegExp('http(s*)://(.*?)/setting/(.*?)', 'g'),
214213
new RegExp('http(s*)://(.*?)/roles', 'g'),
215214
new RegExp('http(s*)://(.*?)/role/options', 'g'),
@@ -222,9 +221,6 @@ function skipLoader(config) {
222221
new RegExp('http(s*)://(.*?)/agent/labels', 'g'),
223222
new RegExp('http(s*)://(.*?)/agent/tasks', 'g'),
224223
new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g'),
225-
new RegExp('http(s*)://(.*?)/conversation', 'g'),
226-
new RegExp('http(s*)://(.*?)/conversations/(.*?)/dialogs', 'g'),
227-
new RegExp('http(s*)://(.*?)/conversations', 'g'),
228224
new RegExp('http(s*)://(.*?)/conversation/state/keys', 'g'),
229225
new RegExp('http(s*)://(.*?)/conversation/(.*?)/files/(.*?)', 'g'),
230226
new RegExp('http(s*)://(.*?)/llm-configs', 'g'),
@@ -235,8 +231,7 @@ function skipLoader(config) {
235231
new RegExp('http(s*)://(.*?)/logger/instruction/log/keys', 'g'),
236232
new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/content-log', 'g'),
237233
new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/state-log', 'g'),
238-
new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g'),
239-
234+
new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g')
240235
];
241236

242237
if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) {
@@ -287,7 +282,9 @@ function skipGlobalError(config) {
287282
];
288283

289284
/** @type {RegExp[]} */
290-
const getRegexes = [];
285+
const getRegexes = [
286+
new RegExp('http(s*)://(.*?)/agents', 'g')
287+
];
291288

292289
if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) {
293290
return true;

src/lib/helpers/utils/common.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,19 @@ export function splitTextByCase(str) {
175175
return text;
176176
}
177177

178+
/**
179+
* @param {string} url
180+
*/
181+
export function getCleanUrl(url) {
182+
if (!url) return url;
183+
184+
if (url.startsWith('/')) {
185+
url = url.substring(1);
186+
}
187+
188+
return url;
189+
}
190+
178191
/**
179192
* @param {string} timeRange
180193
* @returns {{ startTime: string | null, endTime: string | null }}

src/lib/scss/custom/common/_common.scss

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,17 @@ button:focus {
204204
text-overflow: ellipsis;
205205
}
206206
}
207+
208+
.text-btn {
209+
background: none;
210+
border: none;
211+
padding: 0;
212+
color: inherit;
213+
font-weight: 500;
214+
cursor: pointer;
215+
216+
&:hover {
217+
text-decoration: none;
218+
background: none;
219+
}
220+
}

src/lib/scss/custom/components/_loader.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.loader {
2-
position: fixed;
2+
position: absolute;
33
z-index: 9999;
44
background-color: rgba(255, 255, 255, 0.8);
55
top: 0;

src/lib/services/agent-service.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ export async function getSettings() {
1616
* Get agent list
1717
* @param {import('$agentTypes').AgentFilter} filter
1818
* @param {boolean} checkAuth
19+
* @param {AbortSignal | null} signal
1920
* @returns {Promise<import('$commonTypes').PagedItems<import('$agentTypes').AgentModel>>}
2021
*/
21-
export async function getAgents(filter, checkAuth = false) {
22+
export async function getAgents(filter, checkAuth = false, signal = null) {
2223
let url = endpoints.agentListUrl;
2324
const response = await axios.get(url, {
2425
params: {
@@ -28,7 +29,8 @@ export async function getAgents(filter, checkAuth = false) {
2829
paramsSerializer: {
2930
dots: true,
3031
indexes: null,
31-
}
32+
},
33+
signal: signal || undefined
3234
});
3335
return response.data;
3436
}

src/routes/+layout.svelte

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,15 @@
11
<script>
22
import { addMessages, init, getLocaleFromNavigator } from 'svelte-i18n';
33
import en from '$lib/langs/en.json';
4-
import '$lib/helpers/http';
5-
import { onDestroy, onMount } from 'svelte';
6-
import { globalErrorStore, loaderStore } from '$lib/helpers/store';
7-
import Loader from '$lib/common/Loader.svelte';
8-
import LoadingToComplete from '$lib/common/LoadingToComplete.svelte';
94
105
addMessages('en', en);
116
127
init({
138
fallbackLocale: 'en',
149
initialLocale: getLocaleFromNavigator()
1510
});
16-
17-
/** @type {boolean} */
18-
let isLoading = false;
19-
let hasError = false;
20-
21-
/** @type {any} */
22-
let loaderUnsubscriber;
23-
/** @type {any} */
24-
let errorUnsubscriber;
25-
26-
onMount(() => {
27-
window?.speechSynthesis?.cancel();
28-
loaderUnsubscriber = loaderStore.subscribe(value => {
29-
isLoading = value;
30-
});
31-
32-
errorUnsubscriber = globalErrorStore.subscribe(value => {
33-
hasError = value;
34-
});
35-
})
36-
37-
onDestroy(() => {
38-
loaderUnsubscriber?.();
39-
errorUnsubscriber?.();
40-
});
4111
</script>
4212

43-
{#if isLoading}
44-
<Loader size={50}/>
45-
{/if}
46-
47-
<LoadingToComplete isError={hasError} />
48-
4913
<slot />
5014

5115
<style lang="scss">

src/routes/VerticalLayout/Index.svelte

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import { getPluginMenu } from '$lib/services/plugin-service';
66
import { myInfo } from '$lib/services/auth-service';
77
import { globalMenuStore } from '$lib/helpers/store';
8+
import LoadingToComplete from '$lib/common/LoadingToComplete.svelte';
9+
import GlobalHeader from '$lib/common/shared/GlobalHeader.svelte';
810
import Header from './Header.svelte';
911
import Sidebar from './Sidebar.svelte';
1012
import Footer from './Footer.svelte';
@@ -15,6 +17,10 @@
1517
/** @type {import("$userTypes").UserModel} */
1618
let user;
1719
20+
/** @type {boolean} */
21+
let isLoading = false;
22+
let hasError = false;
23+
1824
const toggleRightBar = () => {
1925
if (browser) {
2026
if (document.body.classList.contains('right-bar-enabled')) {
@@ -39,14 +45,21 @@
3945
});
4046
</script>
4147

48+
<GlobalHeader bind:isLoading={isLoading} bind:hasError={hasError} />
49+
4250
<div id="layout-wrapper">
4351
<Header user={user} toggleRightBar={() => toggleRightBar()} />
4452
{#if menu}
4553
<Sidebar menu={menu}/>
4654
{/if}
4755
<div class="main-content">
4856
<div class="page-content">
49-
<div class="container-fluid">
57+
<div class="container-fluid" style="position: relative;">
58+
<LoadingToComplete
59+
spinnerSize={50}
60+
isLoading={isLoading}
61+
isError={hasError}
62+
/>
5063
<slot />
5164
</div>
5265
</div>

src/routes/VerticalLayout/Sidebar.svelte

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
<script>
2-
// @ts-nocheck
3-
2+
// @ts-nocheck
43
import { onMount, afterUpdate } from 'svelte';
5-
import 'overlayscrollbars/overlayscrollbars.css';
6-
import { OverlayScrollbars } from 'overlayscrollbars';
7-
import Link from 'svelte-link';
8-
import { page } from '$app/stores';
94
import { browser } from '$app/environment';
5+
import { goto } from '$app/navigation';
6+
import { page } from '$app/stores';
107
import { _ } from 'svelte-i18n';
8+
import Link from 'svelte-link';
9+
import 'overlayscrollbars/overlayscrollbars.css';
10+
import { OverlayScrollbars } from 'overlayscrollbars';
1111
import { globalEventStore } from '$lib/helpers/store';
12+
import { getCleanUrl } from '$lib/helpers/utils/common';
1213
1314
/** @type {import('$pluginTypes').PluginMenuDefModel[]} */
1415
export let menu;
1516
1617
// after routing complete call afterUpdate function
1718
afterUpdate(() => {
1819
removeActiveDropdown();
19-
const curUrl = getPathUrl();
20+
const curUrl = getCleanUrl($page.url.pathname);
2021
if (curUrl) {
21-
let item = document.querySelector(".vertical-menu a[href='" + curUrl + "']");
22+
const item = document.querySelector(".vertical-menu a[id='" + curUrl + "']");
2223
if (item) {
2324
item.classList.add('mm-active');
2425
const parent1 = item.parentElement;
@@ -62,12 +63,13 @@
6263
6364
onMount(async () => {
6465
const menuElement = document.querySelector('#vertical-menu');
66+
// @ts-ignore
6567
OverlayScrollbars(menuElement, options);
6668
activeMenu();
6769
68-
const curUrl = getPathUrl();
70+
const curUrl = getCleanUrl($page.url.pathname);
6971
if (curUrl) {
70-
let item = document.querySelector(".vertical-menu a[href='" + curUrl + "']");
72+
const item = document.querySelector(".vertical-menu a[id='" + curUrl + "']");
7173
if (item) {
7274
item.classList.add('mm-active');
7375
item.scrollIntoView({ behavior: 'smooth', block: 'center' });
@@ -183,26 +185,28 @@
183185
184186
const menuItemScroll = () => {
185187
if (browser) {
186-
const curUrl = getPathUrl();
187-
let item = document.querySelector(".vertical-menu a[href='" + curUrl + "']")?.offsetTop;
188-
if (item && item > 300) {
189-
item = item - 300;
188+
const curUrl = getCleanUrl($page.url.pathname);
189+
const item = document.querySelector(".vertical-menu a[id='" + curUrl + "']");
190+
// @ts-ignore
191+
let offset = item?.offsetTop;
192+
if (offset && offset > 300) {
193+
offset = offset - 300;
190194
const menuElement = document.getElementById('vertical-menu');
191195
menuElement?.scrollTo({
192-
top: item,
196+
top: offset,
193197
behavior: 'smooth'
194198
});
195199
}
196200
}
197201
};
198202
199-
const getPathUrl = () => {
200-
const path = $page.url.pathname;
201-
return path?.startsWith('/') ? path.substring(1) : path;
202-
};
203+
/** @param {string} url */
204+
const goToPage = (url) => {
205+
if (!url) return;
203206
204-
const goToPage = () => {
207+
url = getCleanUrl(url);
205208
globalEventStore.reset();
209+
goto(url);
206210
}
207211
</script>
208212
@@ -217,33 +221,42 @@
217221
<li class="menu-title" key="t-menu">{$_(item.label)}</li>
218222
{:else if item.subMenu}
219223
<li>
220-
<Link href={null} class="has-arrow waves-effect">
224+
<Link class="has-arrow waves-effect clickable" href={null}>
221225
<i class={item.icon} />
222226
<span>{$_(item.label)}</span>
223227
</Link>
224228
<ul class="sub-menu mm-collapse">
225229
{#each item.subMenu as subMenu}
226230
{#if subMenu.isChildItem}
227231
<li>
228-
<Link href="#" class="has-arrow waves-effect">
232+
<Link class="has-arrow waves-effect clickable" href={null}>
229233
<span>{$_(subMenu.label)}</span>
230234
</Link>
231235
<ul class="sub-menu mm-collapse">
232236
{#each subMenu.childItems as childItem}
233-
<li><Link href={childItem.link} on:click={() => goToPage()}>{$_(childItem.label)}</Link></li>
237+
<li>
238+
<Link class="clickable" id={getCleanUrl(childItem.link)} href={null} on:click={() => goToPage(childItem.link)}>
239+
{$_(childItem.label)}
240+
</Link>
241+
</li>
234242
{/each}
235243
</ul>
236244
</li>
237245
{:else}
238-
<li><Link href={subMenu.link} on:click={() => goToPage()}>{$_(subMenu.label)}</Link></li>
246+
<li>
247+
<Link class="clickable" id={getCleanUrl(subMenu.link)} href={null} on:click={() => goToPage(subMenu.link)}>
248+
{$_(subMenu.label)}
249+
</Link>
250+
</li>
239251
{/if}
240252
{/each}
241253
</ul>
242254
</li>
243255
{:else}
244256
<li>
245-
<Link class="waves-effect" href={item.link} on:click={() => goToPage()} >
246-
<i class={item.icon} /> <span>{$_(item.label)}</span>
257+
<Link class="waves-effect clickable" id={getCleanUrl(item.link)} href={null} on:click={() => goToPage(item.link)} >
258+
<i class={item.icon} />
259+
<span>{$_(item.label)}</span>
247260
</Link>
248261
</li>
249262
{/if}

0 commit comments

Comments
 (0)