diff --git a/api/controllers/console/app/workflow.py b/api/controllers/console/app/workflow.py index 4cc4c29670..6f4beddc56 100644 --- a/api/controllers/console/app/workflow.py +++ b/api/controllers/console/app/workflow.py @@ -1044,7 +1044,7 @@ class WorkflowOnlineUsersApi(Resource): workflow_ids = [id.strip() for id in args["workflow_ids"].split(",")] - results = {} + results = [] for workflow_id in workflow_ids: users_json = redis_client.hgetall(f"workflow_online_users:{workflow_id}") @@ -1054,7 +1054,7 @@ class WorkflowOnlineUsersApi(Resource): users.append(json.loads(user_info_json)) except Exception: continue - results[workflow_id] = users + results.append({"workflow_id": workflow_id, "users": users}) return {"data": results} diff --git a/api/fields/online_user_fields.py b/api/fields/online_user_fields.py index cf54f47902..8fe0dc6a64 100644 --- a/api/fields/online_user_fields.py +++ b/api/fields/online_user_fields.py @@ -1,7 +1,7 @@ from flask_restx import fields online_user_partial_fields = { - "id": fields.String, + "user_id": fields.String, "username": fields.String, "avatar": fields.String, "sid": fields.String, diff --git a/api/services/workflow_service.py b/api/services/workflow_service.py index 2404f81405..36aad4b0fc 100644 --- a/api/services/workflow_service.py +++ b/api/services/workflow_service.py @@ -262,7 +262,7 @@ class WorkflowService: workflow.environment_variables = environment_variables workflow.updated_by = account.id - workflow.updated_at = datetime.now(UTC).replace(tzinfo=None) + workflow.updated_at = naive_utc_now() # commit db session changes db.session.commit() @@ -285,7 +285,7 @@ class WorkflowService: workflow.conversation_variables = conversation_variables workflow.updated_by = account.id - workflow.updated_at = datetime.now(UTC).replace(tzinfo=None) + workflow.updated_at = naive_utc_now() # commit db session changes db.session.commit() @@ -311,7 +311,7 @@ class WorkflowService: workflow.features = json.dumps(features) workflow.updated_by = account.id - workflow.updated_at = datetime.now(UTC).replace(tzinfo=None) + workflow.updated_at = naive_utc_now() # commit db session changes db.session.commit() diff --git a/web/app/components/apps/app-card.tsx b/web/app/components/apps/app-card.tsx index e96793ff72..05f0582463 100644 --- a/web/app/components/apps/app-card.tsx +++ b/web/app/components/apps/app-card.tsx @@ -32,6 +32,8 @@ import { useGlobalPublicStore } from '@/context/global-public-context' import { formatTime } from '@/utils/time' import { useGetUserCanAccessApp } from '@/service/access-control' import dynamic from 'next/dynamic' +import { UserAvatarList } from '@/app/components/base/user-avatar-list' +import type { WorkflowOnlineUser } from '@/models/app' const EditAppModal = dynamic(() => import('@/app/components/explore/create-app-modal'), { ssr: false, @@ -55,9 +57,10 @@ const AccessControl = dynamic(() => import('@/app/components/app/app-access-cont export type AppCardProps = { app: App onRefresh?: () => void + onlineUsers?: WorkflowOnlineUser[] } -const AppCard = ({ app, onRefresh }: AppCardProps) => { +const AppCard = ({ app, onRefresh, onlineUsers = [] }: AppCardProps) => { const { t } = useTranslation() const { notify } = useContext(ToastContext) const systemFeatures = useGlobalPublicStore(s => s.systemFeatures) @@ -331,6 +334,19 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { return `${t('datasetDocuments.segment.editedAt')} ${timeText}` }, [app.updated_at, app.created_at]) + const onlineUserAvatars = useMemo(() => { + if (!onlineUsers.length) + return [] + + return onlineUsers + .map(user => ({ + id: user.user_id || user.sid || '', + name: user.username || 'User', + avatar_url: user.avatar || undefined, + })) + .filter(user => !!user.id) + }, [onlineUsers]) + return ( <>