Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
3248e95d
authored
Aug 24, 2024
by
heheer
Committed by
GitHub
Aug 24, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: undo & redo (#2493)
* fix: undo & redo * fix * fix
parent
3e57c7f5
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
207 additions
and
66 deletions
+207
-66
packages/web/components/common/MyDrawer/CustomRightDrawer.tsx
+2
-1
packages/web/i18n/en/app.json
+1
-0
packages/web/i18n/en/workflow.json
+1
-0
packages/web/i18n/zh/app.json
+1
-0
packages/web/i18n/zh/workflow.json
+1
-0
projects/app/src/pages/api/core/app/version/detail.ts
+22
-0
projects/app/src/pages/api/core/app/version/listWorkflow.tsx
+56
-0
projects/app/src/pages/app/detail/components/Plugin/Header.tsx
+17
-4
projects/app/src/pages/app/detail/components/PublishHistoriesSlider.tsx
+0
-1
projects/app/src/pages/app/detail/components/SimpleApp/Header.tsx
+7
-1
projects/app/src/pages/app/detail/components/Workflow/Header.tsx
+13
-4
projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/FlowController.tsx
+5
-1
projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/SaveAndPublish.tsx
+6
-0
projects/app/src/pages/app/detail/components/WorkflowComponents/context.tsx
+14
-11
projects/app/src/pages/app/detail/components/WorkflowPublishHistoriesSlider.tsx
+44
-27
projects/app/src/pages/app/detail/components/context.tsx
+10
-16
projects/app/src/web/core/app/api/version.ts
+7
-0
No files found.
packages/web/components/common/MyDrawer/CustomRightDrawer.tsx
View file @
3248e95d
...
...
@@ -31,7 +31,8 @@ const CustomRightDrawer = ({
zIndex=
{
100
}
maxW=
{
maxW
}
w=
{
'100%'
}
h=
{
'90vh'
}
top=
{
'60px'
}
bottom=
{
0
}
borderLeftRadius=
{
'lg'
}
border=
{
'base'
}
boxShadow=
{
'2'
}
...
...
packages/web/i18n/en/app.json
View file @
3248e95d
...
...
@@ -92,6 +92,7 @@
"plugin_dispatch_tip"
:
"It is up to the model to decide which plug-ins to add additional capabilities to. If the plug-in is selected, the knowledge base call is also treated as a special plug-in."
,
"publish_channel"
:
"Publish channel"
,
"publish_success"
:
"Publish success"
,
"saved_success"
:
"Saved success"
,
"search_app"
:
"Search app"
,
"setting_app"
:
"Settings"
,
"setting_plugin"
:
"Setting plugin"
,
...
...
packages/web/i18n/en/workflow.json
View file @
3248e95d
...
...
@@ -49,6 +49,7 @@
"workflow"
:
{
"Back_to_current_version"
:
"Back to current version"
,
"My edit"
:
"My edit"
,
"Switch_failed"
:
"Switch failed"
,
"Switch_success"
:
"switch successfully"
,
"Team cloud"
:
"Team cloud"
,
"exit_tips"
:
"Your changes have not been saved. Exiting directly will not save your edits."
...
...
packages/web/i18n/zh/app.json
View file @
3248e95d
...
...
@@ -91,6 +91,7 @@
"plugin_dispatch_tip"
:
"给模型附加额外的能力,具体调用哪些插件,将由模型自主决定。
\n
若选择了插件,知识库调用将自动作为一个特殊的插件。"
,
"publish_channel"
:
"发布渠道"
,
"publish_success"
:
"发布成功"
,
"saved_success"
:
"保存成功"
,
"search_app"
:
"搜索应用"
,
"setting_app"
:
"应用配置"
,
"setting_plugin"
:
"插件配置"
,
...
...
packages/web/i18n/zh/workflow.json
View file @
3248e95d
...
...
@@ -49,6 +49,7 @@
"workflow"
:
{
"Back_to_current_version"
:
"回到初始状态"
,
"My edit"
:
"我的编辑"
,
"Switch_failed"
:
"切换失败"
,
"Switch_success"
:
"切换成功"
,
"Team cloud"
:
"团队云端"
,
"exit_tips"
:
"您的更改尚未保存,「直接退出」将不会保存您的编辑记录。"
...
...
projects/app/src/pages/api/core/app/version/detail.ts
0 → 100644
View file @
3248e95d
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
NextAPI
}
from
'@/service/middleware/entry'
;
import
{
MongoAppVersion
}
from
'@fastgpt/service/core/app/version/schema'
;
import
{
PaginationProps
,
PaginationResponse
}
from
'@fastgpt/web/common/fetch/type'
;
import
{
authApp
}
from
'@fastgpt/service/support/permission/app/auth'
;
import
{
ReadPermissionVal
}
from
'@fastgpt/global/support/permission/constant'
;
type
Props
=
{
versionId
:
string
;
appId
:
string
;
};
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
<
any
>
)
{
const
{
versionId
,
appId
}
=
req
.
query
as
Props
;
await
authApp
({
req
,
authToken
:
true
,
appId
,
per
:
ReadPermissionVal
});
const
result
=
await
MongoAppVersion
.
findById
(
versionId
);
return
result
;
}
export
default
NextAPI
(
handler
);
projects/app/src/pages/api/core/app/version/listWorkflow.tsx
0 → 100644
View file @
3248e95d
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
NextAPI
}
from
'@/service/middleware/entry'
;
import
{
MongoAppVersion
}
from
'@fastgpt/service/core/app/version/schema'
;
import
{
PaginationProps
,
PaginationResponse
}
from
'@fastgpt/web/common/fetch/type'
;
type
Props
=
PaginationProps
<
{
appId
:
string
;
}
>
;
export
type
versionListResponse
=
{
_id
:
string
;
appId
:
string
;
versionName
:
string
;
time
:
Date
;
isPublish
:
boolean
|
undefined
;
tmbId
:
string
;
};
type
Response
=
PaginationResponse
<
versionListResponse
>
;
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
<
any
>
):
Promise
<
Response
>
{
const
{
current
,
pageSize
,
appId
}
=
req
.
body
as
Props
;
const
[
result
,
total
]
=
await
Promise
.
all
([
MongoAppVersion
.
find
(
{
appId
},
'_id appId versionName time isPublish tmbId'
)
.
sort
({
time
:
-
1
})
.
skip
((
current
-
1
)
*
pageSize
)
.
limit
(
pageSize
),
MongoAppVersion
.
countDocuments
({
appId
})
]);
const
versionList
=
result
.
map
((
item
)
=>
{
return
{
_id
:
item
.
_id
,
appId
:
item
.
appId
,
versionName
:
item
.
versionName
,
time
:
item
.
time
,
isPublish
:
item
.
isPublish
,
tmbId
:
item
.
tmbId
};
});
return
{
total
,
list
:
versionList
};
}
export
default
NextAPI
(
handler
);
projects/app/src/pages/app/detail/components/Plugin/Header.tsx
View file @
3248e95d
...
...
@@ -29,6 +29,7 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
import
{
compareSnapshot
}
from
'@/web/core/workflow/utils'
;
import
SaveAndPublishModal
from
'../WorkflowComponents/Flow/components/SaveAndPublish'
;
import
{
formatTime2YMDHMS
}
from
'@fastgpt/global/common/string/time'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
const
PublishHistories
=
dynamic
(()
=>
import
(
'../WorkflowPublishHistoriesSlider'
));
...
...
@@ -36,6 +37,7 @@ const Header = () => {
const
{
t
}
=
useTranslation
();
const
{
isPc
}
=
useSystem
();
const
router
=
useRouter
();
const
{
toast
}
=
useToast
();
const
{
appDetail
,
onPublish
,
currentTab
}
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
);
const
isV2Workflow
=
appDetail
?.
version
===
'v2'
;
...
...
@@ -61,6 +63,9 @@ const Header = () => {
}
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
);
const
isPublished
=
useMemo
(()
=>
{
/*
Find the last saved snapshot in the past and future snapshots
*/
const
savedSnapshot
=
future
.
findLast
((
snapshot
)
=>
snapshot
.
isSaved
)
||
past
.
find
((
snapshot
)
=>
snapshot
.
isSaved
);
...
...
@@ -97,9 +102,10 @@ const Header = () => {
//@ts-ignore
version
:
'v2'
});
// Mark the current snapshot as saved
setPast
((
prevPast
)
=>
prevPast
.
map
((
item
,
index
)
=>
index
===
prevPast
.
length
-
1
index
===
0
?
{
...
item
,
isSaved
:
true
...
...
@@ -171,6 +177,7 @@ const Header = () => {
isLoading=
{
loading
}
onClick=
{
async
()
=>
{
await
onClickSave
({});
onClose
();
onBack
();
}
}
>
...
...
@@ -246,7 +253,7 @@ const Header = () => {
</
Button
>
}
>
{
({})
=>
(
{
({
onClose
})
=>
(
<
MyBox
p=
{
1.5
}
>
<
MyBox
display=
{
'flex'
}
...
...
@@ -259,6 +266,10 @@ const Header = () => {
isLoading=
{
loading
}
onClick=
{
async
()
=>
{
await
onClickSave
({});
toast
({
status
:
'success'
,
title
:
t
(
'app:saved_success'
)
});
}
}
>
<
MyIcon
name=
{
'core/workflow/upload'
}
w=
{
'16px'
}
mr=
{
2
}
/>
...
...
@@ -275,6 +286,7 @@ const Header = () => {
if
(
data
)
{
onSaveAndPublishModalOpen
();
}
onClose
();
}
}
>
<
MyIcon
name=
{
'core/workflow/publish'
}
w=
{
'16px'
}
mr=
{
2
}
/>
...
...
@@ -307,6 +319,8 @@ const Header = () => {
isPc
,
currentTab
,
isPublished
,
onBack
,
onOpen
,
isOpen
,
onClose
,
t
,
...
...
@@ -314,8 +328,6 @@ const Header = () => {
isV2Workflow
,
historiesDefaultData
,
isSave
,
onBack
,
onOpen
,
onClickSave
,
setHistoriesDefaultData
,
appDetail
.
chatConfig
,
...
...
@@ -323,6 +335,7 @@ const Header = () => {
setWorkflowTestData
,
isSaveAndPublishModalOpen
,
onSaveAndPublishModalClose
,
toast
,
onSaveAndPublishModalOpen
]);
...
...
projects/app/src/pages/app/detail/components/PublishHistoriesSlider.tsx
View file @
3248e95d
...
...
@@ -113,7 +113,6 @@ const PublishHistoriesSlider = ({
maxW=
{
'300px'
}
px=
{
0
}
showMask=
{
false
}
top=
{
'60px'
}
overflow=
{
'unset'
}
>
<
Button
...
...
projects/app/src/pages/app/detail/components/SimpleApp/Header.tsx
View file @
3248e95d
...
...
@@ -21,6 +21,7 @@ import MyTag from '@fastgpt/web/components/common/Tag/index';
import
{
publishStatusStyle
}
from
'../constants'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
import
{
useSystem
}
from
'@fastgpt/web/hooks/useSystem'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
const
Header
=
({
appForm
,
...
...
@@ -32,6 +33,7 @@ const Header = ({
const
{
t
}
=
useTranslation
();
const
{
isPc
}
=
useSystem
();
const
router
=
useRouter
();
const
{
toast
}
=
useToast
();
const
{
appId
,
appDetail
,
onPublish
,
currentTab
}
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
);
const
{
data
:
paths
=
[]
}
=
useRequest2
(()
=>
getAppFolderPath
(
appId
),
{
...
...
@@ -75,8 +77,12 @@ const Header = ({
chatConfig
:
data
.
chatConfig
,
type
:
AppTypeEnum
.
simple
});
toast
({
status
:
'success'
,
title
:
t
(
'app:publish_success'
)
});
},
[
onPublish
,
t
]
[
onPublish
,
t
,
toast
]
);
const
[
historiesDefaultData
,
setHistoriesDefaultData
]
=
useState
<
InitProps
>
();
...
...
projects/app/src/pages/app/detail/components/Workflow/Header.tsx
View file @
3248e95d
...
...
@@ -29,6 +29,7 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
import
{
compareSnapshot
}
from
'@/web/core/workflow/utils'
;
import
SaveAndPublishModal
from
'../WorkflowComponents/Flow/components/SaveAndPublish'
;
import
{
formatTime2YMDHMS
}
from
'@fastgpt/global/common/string/time'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
const
PublishHistories
=
dynamic
(()
=>
import
(
'../WorkflowPublishHistoriesSlider'
));
...
...
@@ -36,6 +37,7 @@ const Header = () => {
const
{
t
}
=
useTranslation
();
const
{
isPc
}
=
useSystem
();
const
router
=
useRouter
();
const
{
toast
}
=
useToast
();
const
{
appDetail
,
onPublish
,
currentTab
}
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
);
const
isV2Workflow
=
appDetail
?.
version
===
'v2'
;
...
...
@@ -103,7 +105,7 @@ const Header = () => {
// Mark the current snapshot as saved
setPast
((
prevPast
)
=>
prevPast
.
map
((
item
,
index
)
=>
index
===
prevPast
.
length
-
1
index
===
0
?
{
...
item
,
isSaved
:
true
...
...
@@ -175,6 +177,7 @@ const Header = () => {
isLoading=
{
loading
}
onClick=
{
async
()
=>
{
await
onClickSave
({});
onClose
();
onBack
();
}
}
>
...
...
@@ -250,7 +253,7 @@ const Header = () => {
</
Button
>
}
>
{
({})
=>
(
{
({
onClose
})
=>
(
<
MyBox
p=
{
1.5
}
>
<
MyBox
display=
{
'flex'
}
...
...
@@ -263,6 +266,10 @@ const Header = () => {
isLoading=
{
loading
}
onClick=
{
async
()
=>
{
await
onClickSave
({});
toast
({
status
:
'success'
,
title
:
t
(
'app:saved_success'
)
});
}
}
>
<
MyIcon
name=
{
'core/workflow/upload'
}
w=
{
'16px'
}
mr=
{
2
}
/>
...
...
@@ -279,6 +286,7 @@ const Header = () => {
if
(
data
)
{
onSaveAndPublishModalOpen
();
}
onClose
();
}
}
>
<
MyIcon
name=
{
'core/workflow/publish'
}
w=
{
'16px'
}
mr=
{
2
}
/>
...
...
@@ -311,6 +319,8 @@ const Header = () => {
isPc
,
currentTab
,
isPublished
,
onBack
,
onOpen
,
isOpen
,
onClose
,
t
,
...
...
@@ -318,8 +328,6 @@ const Header = () => {
isV2Workflow
,
historiesDefaultData
,
isSave
,
onBack
,
onOpen
,
onClickSave
,
setHistoriesDefaultData
,
appDetail
.
chatConfig
,
...
...
@@ -327,6 +335,7 @@ const Header = () => {
setWorkflowTestData
,
isSaveAndPublishModalOpen
,
onSaveAndPublishModalClose
,
toast
,
onSaveAndPublishModalOpen
]);
...
...
projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/FlowController.tsx
View file @
3248e95d
...
...
@@ -17,7 +17,11 @@ const FlowController = React.memo(function FlowController() {
useEffect
(()
=>
{
const
keyDownHandler
=
(
event
:
KeyboardEvent
)
=>
{
if
(
event
.
key
===
'z'
&&
(
event
.
ctrlKey
||
event
.
metaKey
)
&&
event
.
shiftKey
)
{
if
(
(
event
.
key
===
'z'
||
event
.
key
===
'Z'
)
&&
(
event
.
ctrlKey
||
event
.
metaKey
)
&&
event
.
shiftKey
)
{
event
.
preventDefault
();
redo
();
}
else
if
(
event
.
key
===
'z'
&&
(
event
.
ctrlKey
||
event
.
metaKey
))
{
...
...
projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/SaveAndPublish.tsx
View file @
3248e95d
import
{
Box
,
Button
,
Input
,
ModalBody
,
ModalFooter
}
from
'@chakra-ui/react'
;
import
MyModal
from
'@fastgpt/web/components/common/MyModal'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
import
{
useForm
}
from
'react-hook-form'
;
import
{
useTranslation
}
from
'react-i18next'
;
type
FormType
=
{
...
...
@@ -17,6 +18,7 @@ const SaveAndPublishModal = ({
onClickSave
:
(
data
:
{
isPublish
:
boolean
;
versionName
:
string
})
=>
Promise
<
void
>
;
})
=>
{
const
{
t
}
=
useTranslation
();
const
{
toast
}
=
useToast
();
const
{
register
,
handleSubmit
}
=
useForm
<
FormType
>
({
defaultValues
:
{
versionName
:
''
,
...
...
@@ -61,6 +63,10 @@ const SaveAndPublishModal = ({
isLoading=
{
isLoading
}
onClick=
{
handleSubmit
(
async
(
data
)
=>
{
await
onClickSave
({
...
data
,
isPublish
:
true
});
toast
({
status
:
'success'
,
title
:
t
(
'app:publish_success'
)
});
onClose
();
})
}
>
...
...
projects/app/src/pages/app/detail/components/WorkflowComponents/context.tsx
View file @
3248e95d
...
...
@@ -15,7 +15,7 @@ import { RuntimeEdgeItemType, StoreEdgeItemType } from '@fastgpt/global/core/wor
import
{
FlowNodeChangeProps
}
from
'@fastgpt/global/core/workflow/type/fe'
;
import
{
FlowNodeInputItemType
}
from
'@fastgpt/global/core/workflow/type/io'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
import
{
useLocalStorageState
,
useMemoizedFn
,
useUpdateEffect
}
from
'ahooks'
;
import
{
use
DebounceEffect
,
use
LocalStorageState
,
useMemoizedFn
,
useUpdateEffect
}
from
'ahooks'
;
import
React
,
{
Dispatch
,
SetStateAction
,
...
...
@@ -900,20 +900,23 @@ const WorkflowContextProvider = ({
return
true
;
},
{
debounceWait
:
500
,
refreshDeps
:
[
nodes
,
edges
,
appDetail
.
chatConfig
,
past
]
}
);
useEffect
(()
=>
{
if
(
!
nodes
.
length
)
return
;
saveSnapshot
({
pastNodes
:
nodes
,
pastEdges
:
edges
,
customTitle
:
formatTime2YMDHMS
(
new
Date
()),
chatConfig
:
appDetail
.
chatConfig
});
},
[
nodes
,
edges
,
appDetail
.
chatConfig
]);
useDebounceEffect
(
()
=>
{
if
(
!
nodes
.
length
)
return
;
saveSnapshot
({
pastNodes
:
nodes
,
pastEdges
:
edges
,
customTitle
:
formatTime2YMDHMS
(
new
Date
()),
chatConfig
:
appDetail
.
chatConfig
});
},
[
nodes
,
edges
,
appDetail
.
chatConfig
],
{
wait
:
500
}
);
const
undo
=
useCallback
(()
=>
{
if
(
past
[
1
])
{
...
...
projects/app/src/pages/app/detail/components/WorkflowPublishHistoriesSlider.tsx
View file @
3248e95d
import
React
,
{
useState
}
from
'react'
;
import
{
getPublishList
,
updateAppVersion
}
from
'@/web/core/app/api/version'
;
import
{
getAppVersionDetail
,
getWorkflowVersionList
,
updateAppVersion
}
from
'@/web/core/app/api/version'
;
import
{
useScrollPagination
}
from
'@fastgpt/web/hooks/useScrollPagination'
;
import
CustomRightDrawer
from
'@fastgpt/web/components/common/MyDrawer/CustomRightDrawer'
;
import
{
useTranslation
}
from
'next-i18next'
;
...
...
@@ -19,15 +23,18 @@ import { useUserStore } from '@/web/support/user/useUserStore';
import
{
useRequest2
}
from
'@fastgpt/web/hooks/useRequest'
;
import
{
useSystemStore
}
from
'@/web/common/system/useSystemStore'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
import
{
versionListResponse
}
from
'@/pages/api/core/app/version/listWorkflow'
;
const
WorkflowPublishHistoriesSlider
=
({
onClose
}:
{
onClose
:
()
=>
void
})
=>
{
const
{
t
}
=
useTranslation
();
const
[
currentTab
,
setCurrentTab
]
=
useState
<
'myEdit'
|
'teamCloud'
>
(
'myEdit'
);
const
[
isLoading
,
setIsLoading
]
=
useState
(
false
);
return
(
<>
<
CustomRightDrawer
onClose=
{
()
=>
onClose
()
}
isLoading=
{
isLoading
}
title=
{
(
<>
...
...
@@ -49,10 +56,9 @@ const WorkflowPublishHistoriesSlider = ({ onClose }: { onClose: () => void }) =>
maxW=
{
'340px'
}
px=
{
0
}
showMask=
{
false
}
top=
{
'60px'
}
overflow=
{
'unset'
}
>
{
currentTab
===
'myEdit'
?
<
MyEdit
/>
:
<
TeamCloud
/>
}
{
currentTab
===
'myEdit'
?
<
MyEdit
/>
:
<
TeamCloud
setIsLoading=
{
setIsLoading
}
/>
}
</
CustomRightDrawer
>
</>
);
...
...
@@ -163,14 +169,14 @@ const MyEdit = () => {
);
};
const
TeamCloud
=
()
=>
{
const
TeamCloud
=
(
{
setIsLoading
}:
{
setIsLoading
:
(
value
:
boolean
)
=>
void
}
)
=>
{
const
{
t
}
=
useTranslation
();
const
{
appDetail
}
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
);
const
{
saveSnapshot
,
resetSnapshot
}
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
);
const
{
loadAndGetTeamMembers
}
=
useUserStore
();
const
{
feConfigs
}
=
useSystemStore
();
const
{
list
,
ScrollList
,
isLoading
,
fetchData
}
=
useScrollPagination
(
get
Publish
List
,
{
const
{
list
,
ScrollList
,
isLoading
,
fetchData
}
=
useScrollPagination
(
get
WorkflowVersion
List
,
{
itemHeight
:
40
,
overscan
:
20
,
...
...
@@ -188,6 +194,37 @@ const TeamCloud = () => {
const
[
isEditing
,
setIsEditing
]
=
useState
(
false
);
const
{
toast
}
=
useToast
();
const
onChangeVersion
=
async
(
versionItem
:
versionListResponse
)
=>
{
setIsLoading
(
true
);
const
versionDetail
=
await
getAppVersionDetail
(
versionItem
.
_id
,
versionItem
.
appId
);
setIsLoading
(
false
);
if
(
!
versionDetail
)
return
;
const
state
=
{
nodes
:
versionDetail
.
nodes
?.
map
((
item
)
=>
storeNode2FlowNode
({
item
})),
edges
:
versionDetail
.
edges
?.
map
((
item
)
=>
storeEdgesRenderEdge
({
edge
:
item
})),
title
:
versionItem
.
versionName
,
chatConfig
:
versionDetail
.
chatConfig
};
const
res
=
await
saveSnapshot
({
pastNodes
:
state
.
nodes
,
pastEdges
:
state
.
edges
,
chatConfig
:
state
.
chatConfig
,
customTitle
:
`
${
t
(
'app:app.version_copy'
)}
-
${
state
.
title
}
`
});
if
(
!
res
)
{
return
toast
({
title
:
t
(
'workflow:workflow.Switch_failed'
),
status
:
'warning'
});
}
resetSnapshot
(
state
);
toast
({
title
:
t
(
'workflow:workflow.Switch_success'
),
status
:
'success'
});
};
return
(
<
ScrollList
isLoading=
{
isLoading
}
flex=
{
'1 0 0'
}
px=
{
5
}
>
{
list
.
map
((
data
,
index
)
=>
{
...
...
@@ -209,28 +246,7 @@ const TeamCloud = () => {
_hover=
{
{
bg
:
'primary.50'
}
}
onClick=
{
async
()
=>
{
const
state
=
{
nodes
:
item
.
nodes
?.
map
((
item
)
=>
storeNode2FlowNode
({
item
})),
edges
:
item
.
edges
?.
map
((
item
)
=>
storeEdgesRenderEdge
({
edge
:
item
})),
title
:
item
.
versionName
,
chatConfig
:
item
.
chatConfig
};
const
res
=
await
saveSnapshot
({
pastNodes
:
state
.
nodes
,
pastEdges
:
state
.
edges
,
chatConfig
:
state
.
chatConfig
,
customTitle
:
`${t('app:app.version_copy')}-${state.title}`
});
if
(
!
res
)
return
;
resetSnapshot
(
state
);
toast
({
title
:
t
(
'workflow:workflow.Switch_success'
),
status
:
'success'
});
}
}
onClick=
{
()
=>
onChangeVersion
(
item
)
}
>
<
MyPopover
trigger=
"hover"
...
...
@@ -308,6 +324,7 @@ const TeamCloud = () => {
autoFocus
h=
{
8
}
defaultValue=
{
item
.
versionName
||
formatTime2YMDHMS
(
item
.
time
)
}
onClick=
{
(
e
)
=>
e
.
stopPropagation
()
}
onBlur=
{
async
(
e
)
=>
{
setIsEditing
(
true
);
await
updateAppVersion
({
...
...
projects/app/src/pages/app/detail/components/context.tsx
View file @
3248e95d
...
...
@@ -84,7 +84,6 @@ export const AppContext = createContext<AppContextType>({
const
AppContextProvider
=
({
children
}:
{
children
:
ReactNode
})
=>
{
const
{
t
}
=
useTranslation
();
const
{
appT
}
=
useI18n
();
const
router
=
useRouter
();
const
{
appId
,
currentTab
=
TabEnum
.
appEdit
}
=
router
.
query
as
{
appId
:
string
;
...
...
@@ -151,23 +150,18 @@ const AppContextProvider = ({ children }: { children: ReactNode }) => {
}));
});
const
{
runAsync
:
onPublish
}
=
useRequest2
(
async
(
data
:
PostPublishAppProps
)
=>
{
await
postPublishApp
(
appId
,
data
);
setAppDetail
((
state
)
=>
({
...
state
,
...
data
,
modules
:
data
.
nodes
||
state
.
modules
}));
reloadAppLatestVersion
();
},
{
successToast
:
appT
(
'publish_success'
)
}
);
const
{
runAsync
:
onPublish
}
=
useRequest2
(
async
(
data
:
PostPublishAppProps
)
=>
{
await
postPublishApp
(
appId
,
data
);
setAppDetail
((
state
)
=>
({
...
state
,
...
data
,
modules
:
data
.
nodes
||
state
.
modules
}));
reloadAppLatestVersion
();
});
const
{
openConfirm
:
openConfirmDel
,
ConfirmModal
:
ConfirmDelModal
}
=
useConfirm
({
content
:
appT
(
'
confirm_del_app_tip'
),
content
:
t
(
'app:
confirm_del_app_tip'
),
type
:
'delete'
});
const
{
runAsync
:
deleteApp
}
=
useRequest2
(
...
...
projects/app/src/web/core/app/api/version.ts
View file @
3248e95d
...
...
@@ -7,6 +7,7 @@ import type {
getLatestVersionResponse
}
from
'@/pages/api/core/app/version/latest'
;
import
{
UpdateAppVersionBody
}
from
'@/pages/api/core/app/version/update'
;
import
{
versionListResponse
}
from
'@/pages/api/core/app/version/listWorkflow'
;
export
const
getAppLatestVersion
=
(
data
:
getLatestVersionQuery
)
=>
GET
<
getLatestVersionResponse
>
(
'/core/app/version/latest'
,
data
);
...
...
@@ -17,6 +18,12 @@ export const postPublishApp = (appId: string, data: PostPublishAppProps) =>
export
const
getPublishList
=
(
data
:
PaginationProps
<
{
appId
:
string
}
>
)
=>
POST
<
PaginationResponse
<
AppVersionSchemaType
>>
(
'/core/app/version/list'
,
data
);
export
const
getWorkflowVersionList
=
(
data
:
PaginationProps
<
{
appId
:
string
}
>
)
=>
POST
<
PaginationResponse
<
versionListResponse
>>
(
'/core/app/version/listWorkflow'
,
data
);
export
const
getAppVersionDetail
=
(
versionId
:
string
,
appId
:
string
)
=>
GET
<
AppVersionSchemaType
>
(
`/core/app/version/detail?versionId=
${
versionId
}
&appId=
${
appId
}
`
);
export
const
postRevertVersion
=
(
appId
:
string
,
data
:
PostRevertAppProps
)
=>
POST
(
`/core/app/version/revert?appId=
${
appId
}
`
,
data
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment