Skip to content

Commit 69dc043

Browse files
authored
feat(front-page): add marketplace navigation with new tab (#1660)
* feat(front-page): add marketplace navigation with new tab * feat(workflow-app): preserve execution state and credit usage on stop
1 parent a683395 commit 69dc043

File tree

5 files changed

+68
-9
lines changed

5 files changed

+68
-9
lines changed

packages/ai-workspace-common/src/components/canvas/front-page/index.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ export const FrontPage = memo(() => {
8282

8383
const handleViewAllWorkflows = useCallback(() => {
8484
navigate('/workflow-list');
85+
}, [navigate]);
86+
87+
const handleViewMarketplace = useCallback(() => {
88+
window.open('/workflow-marketplace', '_blank');
8589
}, []);
8690

8791
useEffect(() => {
@@ -138,7 +142,10 @@ export const FrontPage = memo(() => {
138142
)}
139143

140144
{canvasTemplateEnabled && (
141-
<ModuleContainer title={t('frontPage.template.title')}>
145+
<ModuleContainer
146+
title={t('frontPage.template.title')}
147+
handleTitleClick={handleViewMarketplace}
148+
>
142149
{showTemplateCategories && templateCategories.length > 1 && (
143150
<div className="flex items-center gap-2 flex-wrap">
144151
{templateCategories.map((category) => (

packages/ai-workspace-common/src/components/workflow-app/create-modal.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,16 +577,30 @@ export const CreateWorkflowAppModal = ({
577577
return coverUploading || coverFileList.some((file) => file.status === 'uploading');
578578
}, [coverUploading, coverFileList]);
579579

580+
// Determine if this is an update (existing app) or new publish
581+
const isUpdate = useMemo(() => {
582+
return !!appId || !!appData;
583+
}, [appId, appData]);
584+
585+
// Get title and button text based on whether it's an update or new publish
586+
const modalTitle = useMemo(() => {
587+
return isUpdate ? t('workflowApp.updatePublish') : t('workflowApp.publish');
588+
}, [isUpdate, t]);
589+
590+
const okButtonText = useMemo(() => {
591+
return isUpdate ? t('workflowApp.updatePublish') : t('workflowApp.publish');
592+
}, [isUpdate, t]);
593+
580594
return (
581595
<Modal
582596
centered
583597
open={visible}
584598
onCancel={() => setVisible(false)}
585599
onOk={onSubmit}
586600
confirmLoading={confirmLoading}
587-
okText={t('common.confirm')}
601+
okText={okButtonText}
588602
cancelText={t('common.cancel')}
589-
title={t('workflowApp.publish')}
603+
title={modalTitle}
590604
okButtonProps={{ disabled: isUploading }}
591605
styles={{
592606
body: {

packages/i18n/src/en-US/ui.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,7 @@ const translations = {
38223822
titlePlaceholder: 'Please enter name',
38233823
descriptionPlaceholder: 'Please enter description',
38243824
publish: 'Publish',
3825+
updatePublish: 'Update Publish',
38253826
edit: 'Edit App',
38263827
publishSuccess: 'Published successfully',
38273828
alreadyPublished: 'Already Published',

packages/i18n/src/zh-Hans/ui.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,6 +3555,7 @@ const translations = {
35553555
titlePlaceholder: '请输入名称',
35563556
descriptionPlaceholder: '请输入描述',
35573557
publish: '发布',
3558+
updatePublish: '更新发布',
35583559
edit: '编辑应用',
35593560
publishSuccess: '发布成功',
35603561
alreadyPublished: '已发布',

packages/web-core/src/pages/workflow-app/index.tsx

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -556,18 +556,54 @@ const WorkflowAppPage: React.FC = () => {
556556
);
557557
}
558558

559-
// Clean up frontend state
559+
// Save current executionId before clearing it
560+
const currentExecutionId = executionId;
561+
562+
// Preserve canvasId if available in workflowDetail
563+
if (workflowDetail?.canvasId) {
564+
setCanvasId(workflowDetail.canvasId);
565+
}
566+
567+
// Fetch execution credit usage before clearing executionId
568+
if (currentExecutionId) {
569+
try {
570+
const response = await getClient().getCreditUsageByExecutionId({
571+
query: {
572+
executionId: currentExecutionId,
573+
},
574+
});
575+
if (response?.data?.data?.total) {
576+
setExecutionCreditUsage(response.data.data.total);
577+
}
578+
} catch (error) {
579+
console.error('Failed to fetch execution credit usage:', error);
580+
}
581+
}
582+
583+
// Preserve completed node executions before clearing executionId
584+
// Only keep nodes that have finished status
585+
const completedExecutions = nodeExecutions.filter(
586+
(node: WorkflowNodeExecution) => node.status === 'finish',
587+
);
588+
if (completedExecutions.length > 0) {
589+
setFinalNodeExecutions(completedExecutions);
590+
}
591+
592+
// Clean up frontend state (but preserve completed results and credit usage)
560593
setExecutionId(null);
561594
setIsRunning(false);
562595
setIsStopped(true);
563-
setExecutionCreditUsage(null);
564-
setFinalNodeExecutions([]);
565-
setRuntimeDriveFiles([]);
596+
// Don't clear executionCreditUsage - it's set above if available
597+
// Don't clear finalNodeExecutions - it's set above if available
598+
// Don't clear canvasId - it's set above if available
599+
// Don't clear runtimeDriveFiles - they will be fetched based on finalNodeExecutions and canvasId
566600
stopPolling();
601+
// Refresh credit balance after abort
602+
refetchUsage();
567603
message.success(t('workflowApp.run.stopSuccess'));
568604
},
569605
});
570-
}, [nodeExecutions, stopPolling, t]);
606+
}, [nodeExecutions, stopPolling, t, executionId, workflowDetail, refetchUsage]);
571607

572608
return (
573609
<ReactFlowProvider>
@@ -856,7 +892,7 @@ const WorkflowAppPage: React.FC = () => {
856892
</div>
857893
)}
858894

859-
{logs.length > 0 && (
895+
{(products.length > 0 || logs.length > 0) && (
860896
<>
861897
{/* Tabs */}
862898
<div

0 commit comments

Comments
 (0)