From 3c7bf99e214f553fb5111b27066fb5d2ce9d381f Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Thu, 20 Nov 2025 17:24:29 -0600 Subject: [PATCH 1/4] relocate spinner --- src/lib/common/LoadingToComplete.svelte | 10 +++++++-- src/lib/helpers/http.js | 23 ++++++++++++++------ src/lib/services/role-service.js | 6 ++++- src/routes/page/conversation/+page.svelte | 7 +++++- src/routes/page/instruction/log/+page.svelte | 7 +++--- src/routes/page/roles/+page.svelte | 10 +++++++-- src/routes/page/task/+page.svelte | 6 ++++- src/routes/page/users/+page.svelte | 10 +++++++-- 8 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/lib/common/LoadingToComplete.svelte b/src/lib/common/LoadingToComplete.svelte index 40b7f43f..d0d520a8 100644 --- a/src/lib/common/LoadingToComplete.svelte +++ b/src/lib/common/LoadingToComplete.svelte @@ -5,14 +5,20 @@ export let isLoading = false; export let isComplete = false; export let isError = false; + export let spinnerClasses = ''; + export let spinnerStyles = ''; + export let spinnerSize = 50; export let successText = 'Update completed!'; export let errorText = 'Error!'; - export let spinnerSize = 50; {#if isLoading} - + {/if} diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 43405900..0d6cca7e 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -208,24 +208,32 @@ function skipLoader(config) { /** @type {RegExp[]} */ const getRegexes = [ + new RegExp('http(s*)://(.*?)/plugin/menu', 'g'), + new RegExp('http(s*)://(.*?)/settings', 'g'), new RegExp('http(s*)://(.*?)/setting/(.*?)', 'g'), + new RegExp('http(s*)://(.*?)/roles', 'g'), + new RegExp('http(s*)://(.*?)/role/options', 'g'), + new RegExp('http(s*)://(.*?)/role/(.*?)/details', 'g'), + new RegExp('http(s*)://(.*?)/user/(.*?)/details', 'g'), new RegExp('http(s*)://(.*?)/user/me', 'g'), - new RegExp('http(s*)://(.*?)/plugin/menu', 'g'), new RegExp('http(s*)://(.*?)/address/options(.*?)', 'g'), + new RegExp('http(s*)://(.*?)/agent/options', 'g'), + new RegExp('http(s*)://(.*?)/agent/labels', 'g'), + new RegExp('http(s*)://(.*?)/agent/tasks', 'g'), + new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g'), + new RegExp('http(s*)://(.*?)/conversations', 'g'), + new RegExp('http(s*)://(.*?)/conversation/state/keys', 'g'), new RegExp('http(s*)://(.*?)/conversation/(.*?)/files/(.*?)', 'g'), + new RegExp('http(s*)://(.*?)/llm-configs', 'g'), new RegExp('http(s*)://(.*?)/llm-provider/(.*?)/models', 'g'), new RegExp('http(s*)://(.*?)/knowledge/vector/collections', 'g'), new RegExp('http(s*)://(.*?)/knowledge/vector/(.*?)/exist', 'g'), - new RegExp('http(s*)://(.*?)/role/options', 'g'), - new RegExp('http(s*)://(.*?)/role/(.*?)/details', 'g'), - new RegExp('http(s*)://(.*?)/user/(.*?)/details', 'g'), - new RegExp('http(s*)://(.*?)/agent/labels', 'g'), - new RegExp('http(s*)://(.*?)/conversation/state/keys', 'g'), + new RegExp('http(s*)://(.*?)/logger/instruction/log', 'g'), new RegExp('http(s*)://(.*?)/logger/instruction/log/keys', 'g'), new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/content-log', 'g'), new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/state-log', 'g'), new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g'), - new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g') + ]; if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) { @@ -241,6 +249,7 @@ function skipLoader(config) { } if (config.method === 'get' && getRegexes.some(regex => regex.test(config.url || ''))) { + console.log('url', config.url); return true; } diff --git a/src/lib/services/role-service.js b/src/lib/services/role-service.js index 15f40116..77033144 100644 --- a/src/lib/services/role-service.js +++ b/src/lib/services/role-service.js @@ -1,5 +1,6 @@ import { endpoints } from './api-endpoints.js'; import axios from 'axios'; +import qs from 'qs'; /** * Get role options @@ -17,7 +18,10 @@ export async function getRoleOptions() { * @returns {Promise} */ export async function getRoles(filter = null) { - const response = await axios.post(endpoints.rolesUrl, filter); + const response = await axios.get(endpoints.rolesUrl, { + params: filter, + paramsSerializer: (params) => qs.stringify(params, { encode: false, allowDots: true, arrayFormat: "indices" }) + }); return response.data; } diff --git a/src/routes/page/conversation/+page.svelte b/src/routes/page/conversation/+page.svelte index 6b1908dd..8d2b1bc1 100644 --- a/src/routes/page/conversation/+page.svelte +++ b/src/routes/page/conversation/+page.svelte @@ -414,7 +414,6 @@ - @@ -529,6 +528,12 @@
+ diff --git a/src/routes/page/instruction/log/+page.svelte b/src/routes/page/instruction/log/+page.svelte index d5f5c891..2c0766ac 100644 --- a/src/routes/page/instruction/log/+page.svelte +++ b/src/routes/page/instruction/log/+page.svelte @@ -23,6 +23,7 @@ import { TimeRange } from '$lib/helpers/enums'; import { TIME_RANGE_OPTIONS } from '$lib/helpers/constants'; import LogItem from './log-item.svelte'; + import Loader from '$lib/common/Loader.svelte'; const firstPage = 1; @@ -291,7 +292,6 @@ - @@ -393,6 +393,7 @@
+
@@ -407,9 +408,7 @@ {#each logItems as item, idx (idx)} - + {/each}
diff --git a/src/routes/page/roles/+page.svelte b/src/routes/page/roles/+page.svelte index 0923e8b9..1dba9809 100644 --- a/src/routes/page/roles/+page.svelte +++ b/src/routes/page/roles/+page.svelte @@ -147,8 +147,6 @@ - - @@ -160,6 +158,14 @@
+ diff --git a/src/routes/page/task/+page.svelte b/src/routes/page/task/+page.svelte index 0943cd95..7d85bda6 100644 --- a/src/routes/page/task/+page.svelte +++ b/src/routes/page/task/+page.svelte @@ -260,7 +260,6 @@ - @@ -313,6 +312,11 @@
+
diff --git a/src/routes/page/users/+page.svelte b/src/routes/page/users/+page.svelte index 7b708bff..1f918159 100644 --- a/src/routes/page/users/+page.svelte +++ b/src/routes/page/users/+page.svelte @@ -232,8 +232,6 @@ - - @@ -272,6 +270,14 @@
+
From 4930c3c409ae01107b2d57b997fda221b9f15557 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Thu, 20 Nov 2025 17:54:26 -0600 Subject: [PATCH 2/4] refine spinner in conv page --- src/lib/helpers/http.js | 6 +- .../page/agent/code-scripts/+page.svelte | 112 +++--- .../[conversationId]/+page.svelte | 71 ++-- .../[conversationId]/conv-dialogs.svelte | 11 +- .../page/instruction/testing/+page.svelte | 326 +++++++++--------- 5 files changed, 278 insertions(+), 248 deletions(-) diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 0d6cca7e..f33c447f 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -185,7 +185,7 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/knowledge/vector/(.*?)/create', 'g'), new RegExp('http(s*)://(.*?)/knowledge/document/(.*?)/page', 'g'), new RegExp('http(s*)://(.*?)/users', 'g'), - new RegExp('http(s*)://(.*?)/instruct/chat-completion', 'g'), + new RegExp('http(s*)://(.*?)/instruct/(.*?)', 'g'), new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g'), new RegExp('http(s*)://(.*?)/agent/(.*?)/code-script/generate', 'g'), new RegExp('http(s*)://(.*?)/renew-token', 'g') @@ -217,10 +217,13 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/user/(.*?)/details', 'g'), new RegExp('http(s*)://(.*?)/user/me', 'g'), new RegExp('http(s*)://(.*?)/address/options(.*?)', 'g'), + new RegExp('http(s*)://(.*?)/agents', 'g'), new RegExp('http(s*)://(.*?)/agent/options', 'g'), new RegExp('http(s*)://(.*?)/agent/labels', 'g'), new RegExp('http(s*)://(.*?)/agent/tasks', 'g'), new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g'), + new RegExp('http(s*)://(.*?)/conversation', 'g'), + new RegExp('http(s*)://(.*?)/conversations/(.*?)/dialogs', 'g'), new RegExp('http(s*)://(.*?)/conversations', 'g'), new RegExp('http(s*)://(.*?)/conversation/state/keys', 'g'), new RegExp('http(s*)://(.*?)/conversation/(.*?)/files/(.*?)', 'g'), @@ -249,7 +252,6 @@ function skipLoader(config) { } if (config.method === 'get' && getRegexes.some(regex => regex.test(config.url || ''))) { - console.log('url', config.url); return true; } diff --git a/src/routes/page/agent/code-scripts/+page.svelte b/src/routes/page/agent/code-scripts/+page.svelte index 61009801..9de78f84 100644 --- a/src/routes/page/agent/code-scripts/+page.svelte +++ b/src/routes/page/agent/code-scripts/+page.svelte @@ -174,56 +174,64 @@ - - - - - - -
Agent
- changeAgent(e)} + /> + + + + + + {#if !!selectedAgentId} + + + + {#if ADMIN_ROLES.includes(user?.role || '')} + +
+ + +
- - - -{#if !!selectedAgentId} - - - -{#if ADMIN_ROLES.includes(user?.role || '')} - -
- - -
-
-{/if} -{/if} + {/if} + {/if} + \ No newline at end of file diff --git a/src/routes/page/conversation/[conversationId]/+page.svelte b/src/routes/page/conversation/[conversationId]/+page.svelte index 30c6813c..d4d68e8d 100644 --- a/src/routes/page/conversation/[conversationId]/+page.svelte +++ b/src/routes/page/conversation/[conversationId]/+page.svelte @@ -1,23 +1,34 @@ \ No newline at end of file diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index f33c447f..8e49d548 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -31,7 +31,7 @@ const retryQueue = { /** @param {{config: import('axios').InternalAxiosRequestConfig, resolve: (value: any) => void, reject: (reason?: any) => void}} item */ enqueue(item) { this.queue.push(item); - + console.log('queue', this.queue.length); if (!this.isRefreshingToken) { const user = getUserStore(); if (!isTokenExired(user.expires)) { @@ -130,7 +130,7 @@ axios.interceptors.response.use( loaderStore.set(false); const originalRequest = error?.config || {}; const user = getUserStore(); - console.log("renew token count.", user.renew_token_count); + if (!user?.token || user.renew_token_count >= retryQueue.maxRenewTokenCount) { retryQueue.queue = []; redirectToLogin(); @@ -209,7 +209,6 @@ function skipLoader(config) { /** @type {RegExp[]} */ const getRegexes = [ new RegExp('http(s*)://(.*?)/plugin/menu', 'g'), - new RegExp('http(s*)://(.*?)/settings', 'g'), new RegExp('http(s*)://(.*?)/setting/(.*?)', 'g'), new RegExp('http(s*)://(.*?)/roles', 'g'), new RegExp('http(s*)://(.*?)/role/options', 'g'), @@ -222,9 +221,6 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/agent/labels', 'g'), new RegExp('http(s*)://(.*?)/agent/tasks', 'g'), new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g'), - new RegExp('http(s*)://(.*?)/conversation', 'g'), - new RegExp('http(s*)://(.*?)/conversations/(.*?)/dialogs', 'g'), - new RegExp('http(s*)://(.*?)/conversations', 'g'), new RegExp('http(s*)://(.*?)/conversation/state/keys', 'g'), new RegExp('http(s*)://(.*?)/conversation/(.*?)/files/(.*?)', 'g'), new RegExp('http(s*)://(.*?)/llm-configs', 'g'), @@ -235,8 +231,7 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/logger/instruction/log/keys', 'g'), new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/content-log', 'g'), new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/state-log', 'g'), - new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g'), - + new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g') ]; if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) { @@ -287,7 +282,9 @@ function skipGlobalError(config) { ]; /** @type {RegExp[]} */ - const getRegexes = []; + const getRegexes = [ + new RegExp('http(s*)://(.*?)/agents', 'g') + ]; if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) { return true; diff --git a/src/lib/helpers/utils/common.js b/src/lib/helpers/utils/common.js index e6170626..75c13a82 100644 --- a/src/lib/helpers/utils/common.js +++ b/src/lib/helpers/utils/common.js @@ -175,6 +175,19 @@ export function splitTextByCase(str) { return text; } +/** + * @param {string} url + */ +export function getCleanUrl(url) { + if (!url) return url; + + if (url.startsWith('/')) { + url = url.substring(1); + } + + return url; +} + /** * @param {string} timeRange * @returns {{ startTime: string | null, endTime: string | null }} diff --git a/src/lib/scss/custom/common/_common.scss b/src/lib/scss/custom/common/_common.scss index f23a183f..e4230d5d 100644 --- a/src/lib/scss/custom/common/_common.scss +++ b/src/lib/scss/custom/common/_common.scss @@ -204,3 +204,17 @@ button:focus { text-overflow: ellipsis; } } + +.text-btn { + background: none; + border: none; + padding: 0; + color: inherit; + font-weight: 500; + cursor: pointer; + + &:hover { + text-decoration: none; + background: none; + } +} \ No newline at end of file diff --git a/src/lib/scss/custom/components/_loader.scss b/src/lib/scss/custom/components/_loader.scss index 39c7979d..a095d4ce 100644 --- a/src/lib/scss/custom/components/_loader.scss +++ b/src/lib/scss/custom/components/_loader.scss @@ -1,5 +1,5 @@ .loader { - position: fixed; + position: absolute; z-index: 9999; background-color: rgba(255, 255, 255, 0.8); top: 0; diff --git a/src/lib/services/agent-service.js b/src/lib/services/agent-service.js index 4b6d0995..caa9e172 100644 --- a/src/lib/services/agent-service.js +++ b/src/lib/services/agent-service.js @@ -16,9 +16,10 @@ export async function getSettings() { * Get agent list * @param {import('$agentTypes').AgentFilter} filter * @param {boolean} checkAuth + * @param {AbortSignal | null} signal * @returns {Promise>} */ -export async function getAgents(filter, checkAuth = false) { +export async function getAgents(filter, checkAuth = false, signal = null) { let url = endpoints.agentListUrl; const response = await axios.get(url, { params: { @@ -28,7 +29,8 @@ export async function getAgents(filter, checkAuth = false) { paramsSerializer: { dots: true, indexes: null, - } + }, + signal: signal || undefined }); return response.data; } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index e56fb9f1..783b44c7 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,11 +1,6 @@ -{#if isLoading} - -{/if} - - -