mirror of
https://github.com/langgenius/dify.git
synced 2025-12-19 17:27:16 -05:00
feat: add draft trigger detection to app model and UI (#28163)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -15,11 +15,12 @@ from controllers.console.wraps import (
|
|||||||
setup_required,
|
setup_required,
|
||||||
)
|
)
|
||||||
from core.ops.ops_trace_manager import OpsTraceManager
|
from core.ops.ops_trace_manager import OpsTraceManager
|
||||||
|
from core.workflow.enums import NodeType
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from fields.app_fields import app_detail_fields, app_detail_fields_with_site, app_pagination_fields
|
from fields.app_fields import app_detail_fields, app_detail_fields_with_site, app_pagination_fields
|
||||||
from libs.login import current_account_with_tenant, login_required
|
from libs.login import current_account_with_tenant, login_required
|
||||||
from libs.validators import validate_description_length
|
from libs.validators import validate_description_length
|
||||||
from models import App
|
from models import App, Workflow
|
||||||
from services.app_dsl_service import AppDslService, ImportMode
|
from services.app_dsl_service import AppDslService, ImportMode
|
||||||
from services.app_service import AppService
|
from services.app_service import AppService
|
||||||
from services.enterprise.enterprise_service import EnterpriseService
|
from services.enterprise.enterprise_service import EnterpriseService
|
||||||
@@ -106,6 +107,35 @@ class AppListApi(Resource):
|
|||||||
if str(app.id) in res:
|
if str(app.id) in res:
|
||||||
app.access_mode = res[str(app.id)].access_mode
|
app.access_mode = res[str(app.id)].access_mode
|
||||||
|
|
||||||
|
workflow_capable_app_ids = [
|
||||||
|
str(app.id) for app in app_pagination.items if app.mode in {"workflow", "advanced-chat"}
|
||||||
|
]
|
||||||
|
draft_trigger_app_ids: set[str] = set()
|
||||||
|
if workflow_capable_app_ids:
|
||||||
|
draft_workflows = (
|
||||||
|
db.session.execute(
|
||||||
|
select(Workflow).where(
|
||||||
|
Workflow.version == Workflow.VERSION_DRAFT,
|
||||||
|
Workflow.app_id.in_(workflow_capable_app_ids),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.scalars()
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
trigger_node_types = {
|
||||||
|
NodeType.TRIGGER_WEBHOOK,
|
||||||
|
NodeType.TRIGGER_SCHEDULE,
|
||||||
|
NodeType.TRIGGER_PLUGIN,
|
||||||
|
}
|
||||||
|
for workflow in draft_workflows:
|
||||||
|
for _, node_data in workflow.walk_nodes():
|
||||||
|
if node_data.get("type") in trigger_node_types:
|
||||||
|
draft_trigger_app_ids.add(str(workflow.app_id))
|
||||||
|
break
|
||||||
|
|
||||||
|
for app in app_pagination.items:
|
||||||
|
app.has_draft_trigger = str(app.id) in draft_trigger_app_ids
|
||||||
|
|
||||||
return marshal(app_pagination, app_pagination_fields), 200
|
return marshal(app_pagination, app_pagination_fields), 200
|
||||||
|
|
||||||
@api.doc("create_app")
|
@api.doc("create_app")
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ app_partial_fields = {
|
|||||||
"access_mode": fields.String,
|
"access_mode": fields.String,
|
||||||
"create_user_name": fields.String,
|
"create_user_name": fields.String,
|
||||||
"author_name": fields.String,
|
"author_name": fields.String,
|
||||||
|
"has_draft_trigger": fields.Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -282,21 +282,23 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
(!systemFeatures.webapp_auth.enabled)
|
!app.has_draft_trigger && (
|
||||||
? <>
|
(!systemFeatures.webapp_auth.enabled)
|
||||||
<Divider className="my-1" />
|
? <>
|
||||||
<button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
|
|
||||||
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
: !(isGettingUserCanAccessApp || !userCanAccessApp?.result) && (
|
|
||||||
<>
|
|
||||||
<Divider className="my-1" />
|
<Divider className="my-1" />
|
||||||
<button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
|
<button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
|
||||||
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
|
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
)
|
: !(isGettingUserCanAccessApp || !userCanAccessApp?.result) && (
|
||||||
|
<>
|
||||||
|
<Divider className="my-1" />
|
||||||
|
<button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
|
||||||
|
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
<Divider className="my-1" />
|
<Divider className="my-1" />
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -379,6 +379,8 @@ export type App = {
|
|||||||
/** access control */
|
/** access control */
|
||||||
access_mode: AccessMode
|
access_mode: AccessMode
|
||||||
max_active_requests?: number | null
|
max_active_requests?: number | null
|
||||||
|
/** whether workflow trigger has un-published draft */
|
||||||
|
has_draft_trigger?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AppSSO = {
|
export type AppSSO = {
|
||||||
|
|||||||
Reference in New Issue
Block a user