From e954e0d6c4d269b1be37e10fcefda32d58cd48f8 Mon Sep 17 00:00:00 2001 From: jZonG Date: Mon, 24 Feb 2025 20:31:32 +0800 Subject: [PATCH 1/5] feat: time period filter for workflow logs --- .../components/app/workflow-log/filter.tsx | 31 ++++++++++++++++++- web/app/components/app/workflow-log/index.tsx | 14 +++++++-- .../nodes/_base/components/output-vars.tsx | 2 +- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/web/app/components/app/workflow-log/filter.tsx b/web/app/components/app/workflow-log/filter.tsx index d25f938719..f5756ee183 100644 --- a/web/app/components/app/workflow-log/filter.tsx +++ b/web/app/components/app/workflow-log/filter.tsx @@ -2,11 +2,29 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' +import dayjs from 'dayjs' +import { RiCalendarLine } from '@remixicon/react' +import quarterOfYear from 'dayjs/plugin/quarterOfYear' import type { QueryParam } from './index' import Chip from '@/app/components/base/chip' import Input from '@/app/components/base/input' +dayjs.extend(quarterOfYear) -interface IFilterProps { +const today = dayjs() + +export const TIME_PERIOD_MAPPING: { [key: string]: { value: number; name: string } } = { + 1: { value: 0, name: 'today' }, + 2: { value: 7, name: 'last7days' }, + 3: { value: 28, name: 'last4weeks' }, + 4: { value: today.diff(today.subtract(3, 'month'), 'day'), name: 'last3months' }, + 5: { value: today.diff(today.subtract(12, 'month'), 'day'), name: 'last12months' }, + 6: { value: today.diff(today.startOf('month'), 'day'), name: 'monthToDate' }, + 7: { value: today.diff(today.startOf('quarter'), 'day'), name: 'quarterToDate' }, + 8: { value: today.diff(today.startOf('year'), 'day'), name: 'yearToDate' }, + 9: { value: -1, name: 'allTime' }, +} + +type IFilterProps = { queryParams: QueryParam setQueryParams: (v: QueryParam) => void } @@ -27,6 +45,17 @@ const Filter: FC = ({ queryParams, setQueryParams }: IFilterProps) { value: 'stopped', name: 'Stop' }, ]} /> + } + value={queryParams.period} + onSelect={(item) => { + setQueryParams({ ...queryParams, period: item.value }) + }} + onClear={() => setQueryParams({ ...queryParams, period: '9' })} + items={Object.entries(TIME_PERIOD_MAPPING).map(([k, v]) => ({ value: k, name: t(`appLog.filter.period.${v.name}`) }))} + /> = ({ appUrl }) => { const Logs: FC = ({ appDetail }) => { const { t } = useTranslation() - const [queryParams, setQueryParams] = useState({ status: 'all' }) + const [queryParams, setQueryParams] = useState({ status: 'all', period: '2' }) const [currPage, setCurrPage] = React.useState(0) const debouncedQueryParams = useDebounce(queryParams, { wait: 500 }) const [limit, setLimit] = React.useState(APP_PAGE_LIMIT) @@ -58,6 +61,13 @@ const Logs: FC = ({ appDetail }) => { limit, ...(debouncedQueryParams.status !== 'all' ? { status: debouncedQueryParams.status } : {}), ...(debouncedQueryParams.keyword ? { keyword: debouncedQueryParams.keyword } : {}), + ...((debouncedQueryParams.period !== '9') + ? { + start: dayjs().subtract(TIME_PERIOD_MAPPING[debouncedQueryParams.period].value, 'day').startOf('day').format('YYYY-MM-DD HH:mm'), + end: dayjs().endOf('day').format('YYYY-MM-DD HH:mm'), + } + : {}), + ...omit(debouncedQueryParams, ['period', 'status']), } const getWebAppType = (appType: AppMode) => { diff --git a/web/app/components/workflow/nodes/_base/components/output-vars.tsx b/web/app/components/workflow/nodes/_base/components/output-vars.tsx index 4a265a5a5b..cedf63a08a 100644 --- a/web/app/components/workflow/nodes/_base/components/output-vars.tsx +++ b/web/app/components/workflow/nodes/_base/components/output-vars.tsx @@ -42,7 +42,7 @@ export const VarItem: FC = ({
{name}
-
{type}
+
{type}
{description} From e8243c566ffae90dd21879042aa9d5a71ea2bfd0 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Tue, 4 Mar 2025 15:10:21 +0800 Subject: [PATCH 2/5] feat: add time-based filtering for workflow logs Signed-off-by: -LAN- --- .../console/app/workflow_app_log.py | 6 ++++++ api/services/workflow_app_service.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/api/controllers/console/app/workflow_app_log.py b/api/controllers/console/app/workflow_app_log.py index 882c53e4fb..3f121411c9 100644 --- a/api/controllers/console/app/workflow_app_log.py +++ b/api/controllers/console/app/workflow_app_log.py @@ -24,6 +24,12 @@ class WorkflowAppLogApi(Resource): parser = reqparse.RequestParser() parser.add_argument("keyword", type=str, location="args") parser.add_argument("status", type=str, choices=["succeeded", "failed", "stopped"], location="args") + parser.add_argument( + "created_at__before", type=str, location="args", help="Filter logs created before this timestamp" + ) + parser.add_argument( + "created_at__after", type=str, location="args", help="Filter logs created after this timestamp" + ) parser.add_argument("page", type=int_range(1, 99999), default=1, location="args") parser.add_argument("limit", type=int_range(1, 100), default=20, location="args") args = parser.parse_args() diff --git a/api/services/workflow_app_service.py b/api/services/workflow_app_service.py index 7eab0ac1d8..ec0290a3ef 100644 --- a/api/services/workflow_app_service.py +++ b/api/services/workflow_app_service.py @@ -1,4 +1,5 @@ import uuid +from datetime import datetime from flask_sqlalchemy.pagination import Pagination from sqlalchemy import and_, or_ @@ -49,6 +50,23 @@ class WorkflowAppService: # join with workflow_run and filter by status query = query.filter(WorkflowRun.status == status.value) + # Add time-based filtering + created_at_before = args.get("created_at__before") + if created_at_before: + try: + before_date = datetime.fromisoformat(created_at_before.replace("Z", "+00:00")) + query = query.filter(WorkflowAppLog.created_at <= before_date) + except ValueError: + pass # Ignore invalid date format + + created_at_after = args.get("created_at__after") + if created_at_after: + try: + after_date = datetime.fromisoformat(created_at_after.replace("Z", "+00:00")) + query = query.filter(WorkflowAppLog.created_at >= after_date) + except ValueError: + pass # Ignore invalid date format + query = query.order_by(WorkflowAppLog.created_at.desc()) pagination = db.paginate(query, page=args["page"], per_page=args["limit"], error_out=False) From 6460282f4851e3689c83ac72dbc97e24704c3f37 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Tue, 4 Mar 2025 15:34:58 +0800 Subject: [PATCH 3/5] feat: implement SQLAlchemy 2.0 style pagination for workflow app logs with time-based filtering Signed-off-by: -LAN- --- .../console/app/workflow_app_log.py | 11 ++-- api/controllers/service_api/app/workflow.py | 12 ++-- api/fields/workflow_app_log_fields.py | 2 +- api/services/workflow_app_service.py | 57 ++++++++++++------- 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/api/controllers/console/app/workflow_app_log.py b/api/controllers/console/app/workflow_app_log.py index 3f121411c9..e35fdc2c63 100644 --- a/api/controllers/console/app/workflow_app_log.py +++ b/api/controllers/console/app/workflow_app_log.py @@ -1,9 +1,11 @@ from flask_restful import Resource, marshal_with, reqparse # type: ignore from flask_restful.inputs import int_range # type: ignore +from sqlalchemy.orm import Session from controllers.console import api from controllers.console.app.wraps import get_app_model from controllers.console.wraps import account_initialization_required, setup_required +from extensions.ext_database import db from fields.workflow_app_log_fields import workflow_app_log_pagination_fields from libs.login import login_required from models import App @@ -36,11 +38,12 @@ class WorkflowAppLogApi(Resource): # get paginate workflow app logs workflow_app_service = WorkflowAppService() - workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs( - app_model=app_model, args=args - ) + with Session(db.engine) as session: + workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs( + session=session, app_model=app_model, args=args + ) - return workflow_app_log_pagination + return workflow_app_log_pagination api.add_resource(WorkflowAppLogApi, "/apps//workflow-app-logs") diff --git a/api/controllers/service_api/app/workflow.py b/api/controllers/service_api/app/workflow.py index df637b025f..cdbea220ea 100644 --- a/api/controllers/service_api/app/workflow.py +++ b/api/controllers/service_api/app/workflow.py @@ -2,6 +2,7 @@ import logging from flask_restful import Resource, fields, marshal_with, reqparse # type: ignore from flask_restful.inputs import int_range # type: ignore +from sqlalchemy.orm import Session from werkzeug.exceptions import InternalServerError from controllers.service_api import api @@ -125,17 +126,20 @@ class WorkflowAppLogApi(Resource): parser = reqparse.RequestParser() parser.add_argument("keyword", type=str, location="args") parser.add_argument("status", type=str, choices=["succeeded", "failed", "stopped"], location="args") + parser.add_argument("created_at__before", type=str, location="args") + parser.add_argument("created_at__after", type=str, location="args") parser.add_argument("page", type=int_range(1, 99999), default=1, location="args") parser.add_argument("limit", type=int_range(1, 100), default=20, location="args") args = parser.parse_args() # get paginate workflow app logs workflow_app_service = WorkflowAppService() - workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs( - app_model=app_model, args=args - ) + with Session(db.engine) as session: + workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs( + session=session, app_model=app_model, args=args + ) - return workflow_app_log_pagination + return workflow_app_log_pagination api.add_resource(WorkflowRunApi, "/workflows/run") diff --git a/api/fields/workflow_app_log_fields.py b/api/fields/workflow_app_log_fields.py index c45b33597b..0c032ca435 100644 --- a/api/fields/workflow_app_log_fields.py +++ b/api/fields/workflow_app_log_fields.py @@ -20,5 +20,5 @@ workflow_app_log_pagination_fields = { "limit": fields.Integer(attribute="per_page"), "total": fields.Integer, "has_more": fields.Boolean(attribute="has_next"), - "data": fields.List(fields.Nested(workflow_app_log_partial_fields), attribute="items"), + "data": fields.List(fields.Nested(workflow_app_log_partial_fields)), } diff --git a/api/services/workflow_app_service.py b/api/services/workflow_app_service.py index ec0290a3ef..c992109000 100644 --- a/api/services/workflow_app_service.py +++ b/api/services/workflow_app_service.py @@ -1,31 +1,33 @@ import uuid from datetime import datetime -from flask_sqlalchemy.pagination import Pagination -from sqlalchemy import and_, or_ +from sqlalchemy import and_, func, or_, select +from sqlalchemy.orm import Session -from extensions.ext_database import db from models import App, EndUser, WorkflowAppLog, WorkflowRun from models.enums import CreatedByRole from models.workflow import WorkflowRunStatus class WorkflowAppService: - def get_paginate_workflow_app_logs(self, app_model: App, args: dict) -> Pagination: + def get_paginate_workflow_app_logs(self, *, session: Session, app_model: App, args: dict) -> dict: """ - Get paginate workflow app logs - :param app: app model + Get paginate workflow app logs using SQLAlchemy 2.0 style + :param app_model: app model :param args: request args - :return: + :param session: SQLAlchemy session, if None will use db + :return: Pagination object """ - query = db.select(WorkflowAppLog).where( + # Build base statement using SQLAlchemy 2.0 style + stmt = select(WorkflowAppLog).where( WorkflowAppLog.tenant_id == app_model.tenant_id, WorkflowAppLog.app_id == app_model.id ) status = WorkflowRunStatus.value_of(args.get("status", "")) if args.get("status") else None - keyword = args["keyword"] + keyword = args.get("keyword") + if keyword or status: - query = query.join(WorkflowRun, WorkflowRun.id == WorkflowAppLog.workflow_run_id) + stmt = stmt.join(WorkflowRun, WorkflowRun.id == WorkflowAppLog.workflow_run_id) if keyword: keyword_like_val = f"%{keyword[:30].encode('unicode_escape').decode('utf-8')}%".replace(r"\u", r"\\u") @@ -41,21 +43,21 @@ class WorkflowAppService: if keyword_uuid: keyword_conditions.append(WorkflowRun.id == keyword_uuid) - query = query.outerjoin( + stmt = stmt.outerjoin( EndUser, and_(WorkflowRun.created_by == EndUser.id, WorkflowRun.created_by_role == CreatedByRole.END_USER), - ).filter(or_(*keyword_conditions)) + ).where(or_(*keyword_conditions)) if status: - # join with workflow_run and filter by status - query = query.filter(WorkflowRun.status == status.value) + # filter by status + stmt = stmt.where(WorkflowRun.status == status.value) # Add time-based filtering created_at_before = args.get("created_at__before") if created_at_before: try: before_date = datetime.fromisoformat(created_at_before.replace("Z", "+00:00")) - query = query.filter(WorkflowAppLog.created_at <= before_date) + stmt = stmt.where(WorkflowAppLog.created_at <= before_date) except ValueError: pass # Ignore invalid date format @@ -63,15 +65,32 @@ class WorkflowAppService: if created_at_after: try: after_date = datetime.fromisoformat(created_at_after.replace("Z", "+00:00")) - query = query.filter(WorkflowAppLog.created_at >= after_date) + stmt = stmt.where(WorkflowAppLog.created_at >= after_date) except ValueError: pass # Ignore invalid date format - query = query.order_by(WorkflowAppLog.created_at.desc()) + stmt = stmt.order_by(WorkflowAppLog.created_at.desc()) - pagination = db.paginate(query, page=args["page"], per_page=args["limit"], error_out=False) + page = args["page"] + per_page = args["limit"] - return pagination + # Get total count using the same filters + count_stmt = select(func.count()).select_from(stmt.subquery()) + total = session.scalar(count_stmt) + + # Apply pagination limits + offset_stmt = stmt.offset((page - 1) * per_page).limit(per_page) + + # Execute query and get items + items = list(session.scalars(offset_stmt).all()) + + return { + "page": page, + "limit": per_page, + "total": total, + "has_more": total > page * per_page, + "data": items, + } @staticmethod def _safe_parse_uuid(value: str): From 086254c0b10d12f5a00d51c67d98e0a3cafdf0df Mon Sep 17 00:00:00 2001 From: -LAN- Date: Tue, 4 Mar 2025 15:53:27 +0800 Subject: [PATCH 4/5] feat: enhance workflow app log pagination with time-based filtering and status support Signed-off-by: -LAN- --- .../console/app/workflow_app_log.py | 19 ++++++- api/controllers/service_api/app/workflow.py | 19 ++++++- api/fields/workflow_app_log_fields.py | 4 +- api/models/workflow.py | 13 ----- api/services/workflow_app_service.py | 53 +++++++++---------- 5 files changed, 63 insertions(+), 45 deletions(-) diff --git a/api/controllers/console/app/workflow_app_log.py b/api/controllers/console/app/workflow_app_log.py index e35fdc2c63..54640b1a19 100644 --- a/api/controllers/console/app/workflow_app_log.py +++ b/api/controllers/console/app/workflow_app_log.py @@ -1,3 +1,5 @@ +from datetime import datetime + from flask_restful import Resource, marshal_with, reqparse # type: ignore from flask_restful.inputs import int_range # type: ignore from sqlalchemy.orm import Session @@ -10,6 +12,7 @@ from fields.workflow_app_log_fields import workflow_app_log_pagination_fields from libs.login import login_required from models import App from models.model import AppMode +from models.workflow import WorkflowRunStatus from services.workflow_app_service import WorkflowAppService @@ -36,11 +39,25 @@ class WorkflowAppLogApi(Resource): parser.add_argument("limit", type=int_range(1, 100), default=20, location="args") args = parser.parse_args() + args.status = WorkflowRunStatus(args.status) if args.status else None + if args.created_at__before: + args.created_at__before = datetime.fromisoformat(args.created_at__before.replace("Z", "+00:00")) + + if args.created_at__after: + args.created_at__after = datetime.fromisoformat(args.created_at__after.replace("Z", "+00:00")) + # get paginate workflow app logs workflow_app_service = WorkflowAppService() with Session(db.engine) as session: workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs( - session=session, app_model=app_model, args=args + session=session, + app_model=app_model, + keyword=args.keyword, + status=args.status, + created_at_before=args.created_at__before, + created_at_after=args.created_at__after, + page=args.page, + limit=args.limit, ) return workflow_app_log_pagination diff --git a/api/controllers/service_api/app/workflow.py b/api/controllers/service_api/app/workflow.py index cdbea220ea..db8f031547 100644 --- a/api/controllers/service_api/app/workflow.py +++ b/api/controllers/service_api/app/workflow.py @@ -1,4 +1,5 @@ import logging +from datetime import datetime from flask_restful import Resource, fields, marshal_with, reqparse # type: ignore from flask_restful.inputs import int_range # type: ignore @@ -26,7 +27,7 @@ from extensions.ext_database import db from fields.workflow_app_log_fields import workflow_app_log_pagination_fields from libs import helper from models.model import App, AppMode, EndUser -from models.workflow import WorkflowRun +from models.workflow import WorkflowRun, WorkflowRunStatus from services.app_generate_service import AppGenerateService from services.workflow_app_service import WorkflowAppService @@ -132,11 +133,25 @@ class WorkflowAppLogApi(Resource): parser.add_argument("limit", type=int_range(1, 100), default=20, location="args") args = parser.parse_args() + args.status = WorkflowRunStatus(args.status) if args.status else None + if args.created_at__before: + args.created_at__before = datetime.fromisoformat(args.created_at__before.replace("Z", "+00:00")) + + if args.created_at__after: + args.created_at__after = datetime.fromisoformat(args.created_at__after.replace("Z", "+00:00")) + # get paginate workflow app logs workflow_app_service = WorkflowAppService() with Session(db.engine) as session: workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs( - session=session, app_model=app_model, args=args + session=session, + app_model=app_model, + keyword=args.keyword, + status=args.status, + created_at_before=args.created_at__before, + created_at_after=args.created_at__after, + page=args.page, + limit=args.limit, ) return workflow_app_log_pagination diff --git a/api/fields/workflow_app_log_fields.py b/api/fields/workflow_app_log_fields.py index 0c032ca435..e8f8684ae0 100644 --- a/api/fields/workflow_app_log_fields.py +++ b/api/fields/workflow_app_log_fields.py @@ -17,8 +17,8 @@ workflow_app_log_partial_fields = { workflow_app_log_pagination_fields = { "page": fields.Integer, - "limit": fields.Integer(attribute="per_page"), + "limit": fields.Integer, "total": fields.Integer, - "has_more": fields.Boolean(attribute="has_next"), + "has_more": fields.Boolean, "data": fields.List(fields.Nested(workflow_app_log_partial_fields)), } diff --git a/api/models/workflow.py b/api/models/workflow.py index 5af2590e50..f9b697396c 100644 --- a/api/models/workflow.py +++ b/api/models/workflow.py @@ -343,19 +343,6 @@ class WorkflowRunStatus(StrEnum): STOPPED = "stopped" PARTIAL_SUCCESSED = "partial-succeeded" - @classmethod - def value_of(cls, value: str) -> "WorkflowRunStatus": - """ - Get value of given mode. - - :param value: mode value - :return: mode - """ - for mode in cls: - if mode.value == value: - return mode - raise ValueError(f"invalid workflow run status value {value}") - class WorkflowRun(Base): """ diff --git a/api/services/workflow_app_service.py b/api/services/workflow_app_service.py index c992109000..e526517b51 100644 --- a/api/services/workflow_app_service.py +++ b/api/services/workflow_app_service.py @@ -10,12 +10,28 @@ from models.workflow import WorkflowRunStatus class WorkflowAppService: - def get_paginate_workflow_app_logs(self, *, session: Session, app_model: App, args: dict) -> dict: + def get_paginate_workflow_app_logs( + self, + *, + session: Session, + app_model: App, + keyword: str | None = None, + status: WorkflowRunStatus | None = None, + created_at_before: datetime | None = None, + created_at_after: datetime | None = None, + page: int = 1, + limit: int = 20, + ) -> dict: """ Get paginate workflow app logs using SQLAlchemy 2.0 style + :param session: SQLAlchemy session :param app_model: app model - :param args: request args - :param session: SQLAlchemy session, if None will use db + :param keyword: search keyword + :param status: filter by status + :param created_at_before: filter logs created before this timestamp + :param created_at_after: filter logs created after this timestamp + :param page: page number + :param limit: items per page :return: Pagination object """ # Build base statement using SQLAlchemy 2.0 style @@ -23,9 +39,6 @@ class WorkflowAppService: WorkflowAppLog.tenant_id == app_model.tenant_id, WorkflowAppLog.app_id == app_model.id ) - status = WorkflowRunStatus.value_of(args.get("status", "")) if args.get("status") else None - keyword = args.get("keyword") - if keyword or status: stmt = stmt.join(WorkflowRun, WorkflowRun.id == WorkflowAppLog.workflow_run_id) @@ -49,46 +62,32 @@ class WorkflowAppService: ).where(or_(*keyword_conditions)) if status: - # filter by status - stmt = stmt.where(WorkflowRun.status == status.value) + stmt = stmt.where(WorkflowRun.status == status) # Add time-based filtering - created_at_before = args.get("created_at__before") if created_at_before: - try: - before_date = datetime.fromisoformat(created_at_before.replace("Z", "+00:00")) - stmt = stmt.where(WorkflowAppLog.created_at <= before_date) - except ValueError: - pass # Ignore invalid date format + stmt = stmt.where(WorkflowAppLog.created_at <= created_at_before) - created_at_after = args.get("created_at__after") if created_at_after: - try: - after_date = datetime.fromisoformat(created_at_after.replace("Z", "+00:00")) - stmt = stmt.where(WorkflowAppLog.created_at >= after_date) - except ValueError: - pass # Ignore invalid date format + stmt = stmt.where(WorkflowAppLog.created_at >= created_at_after) stmt = stmt.order_by(WorkflowAppLog.created_at.desc()) - page = args["page"] - per_page = args["limit"] - # Get total count using the same filters count_stmt = select(func.count()).select_from(stmt.subquery()) - total = session.scalar(count_stmt) + total = session.scalar(count_stmt) or 0 # Apply pagination limits - offset_stmt = stmt.offset((page - 1) * per_page).limit(per_page) + offset_stmt = stmt.offset((page - 1) * limit).limit(limit) # Execute query and get items items = list(session.scalars(offset_stmt).all()) return { "page": page, - "limit": per_page, + "limit": limit, "total": total, - "has_more": total > page * per_page, + "has_more": total > page * limit, "data": items, } From 651ec24152293597d5aa8afd66b895d7d002f036 Mon Sep 17 00:00:00 2001 From: jZonG Date: Tue, 4 Mar 2025 17:37:29 +0800 Subject: [PATCH 5/5] use ISO time --- web/app/components/app/workflow-log/index.tsx | 11 +++++++++-- web/service/log.ts | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/web/app/components/app/workflow-log/index.tsx b/web/app/components/app/workflow-log/index.tsx index 62897a3c38..5d7dd7531c 100644 --- a/web/app/components/app/workflow-log/index.tsx +++ b/web/app/components/app/workflow-log/index.tsx @@ -6,6 +6,8 @@ import { usePathname } from 'next/navigation' import { useDebounce } from 'ahooks' import { omit } from 'lodash-es' import dayjs from 'dayjs' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' import { Trans, useTranslation } from 'react-i18next' import Link from 'next/link' import List from './list' @@ -15,6 +17,10 @@ import Loading from '@/app/components/base/loading' import { fetchWorkflowLogs } from '@/service/log' import { APP_PAGE_LIMIT } from '@/config' import type { App, AppMode } from '@/types/app' +import { useAppContext } from '@/context/app-context' + +dayjs.extend(utc) +dayjs.extend(timezone) export type ILogsProps = { appDetail: App @@ -51,6 +57,7 @@ const EmptyElement: FC<{ appUrl: string }> = ({ appUrl }) => { const Logs: FC = ({ appDetail }) => { const { t } = useTranslation() + const { userProfile: { timezone } } = useAppContext() const [queryParams, setQueryParams] = useState({ status: 'all', period: '2' }) const [currPage, setCurrPage] = React.useState(0) const debouncedQueryParams = useDebounce(queryParams, { wait: 500 }) @@ -63,8 +70,8 @@ const Logs: FC = ({ appDetail }) => { ...(debouncedQueryParams.keyword ? { keyword: debouncedQueryParams.keyword } : {}), ...((debouncedQueryParams.period !== '9') ? { - start: dayjs().subtract(TIME_PERIOD_MAPPING[debouncedQueryParams.period].value, 'day').startOf('day').format('YYYY-MM-DD HH:mm'), - end: dayjs().endOf('day').format('YYYY-MM-DD HH:mm'), + created_at__after: dayjs().subtract(TIME_PERIOD_MAPPING[debouncedQueryParams.period].value, 'day').startOf('day').tz(timezone).format('YYYY-MM-DDTHH:mm:ssZ'), + created_at__before: dayjs().endOf('day').tz(timezone).format('YYYY-MM-DDTHH:mm:ssZ'), } : {}), ...omit(debouncedQueryParams, ['period', 'status']), diff --git a/web/service/log.ts b/web/service/log.ts index ec22785e40..4bb4626b87 100644 --- a/web/service/log.ts +++ b/web/service/log.ts @@ -17,7 +17,6 @@ import type { LogMessageAnnotationsResponse, LogMessageFeedbacksRequest, LogMessageFeedbacksResponse, - WorkflowLogsRequest, WorkflowLogsResponse, WorkflowRunDetailResponse, } from '@/models/log' @@ -64,7 +63,7 @@ export const fetchAnnotationsCount: Fetcher(url) } -export const fetchWorkflowLogs: Fetcher = ({ url, params }) => { +export const fetchWorkflowLogs: Fetcher }> = ({ url, params }) => { return get(url, { params }) }