diff --git a/ui/web/public/locales/en/common.json b/ui/web/public/locales/en/common.json index 94034ca25..cdcce0e85 100644 --- a/ui/web/public/locales/en/common.json +++ b/ui/web/public/locales/en/common.json @@ -18,6 +18,7 @@ "decline": "Decline", "default": "Default", "delete": "delete", + "edit": "Edit", "empty": "No data", "export": "Export", "export_succeed": "Exported succeed", @@ -38,6 +39,7 @@ "other": "Other", "position_long": "", "position_short": "", + "recover": "Recover", "reference_error": "Reference error: Unable to find {{source}} in {{importer}}, please check if the file exists in the workspace.", "report_bug": "Report", "reset": "Reset", diff --git a/ui/web/public/locales/zh-Hans/common.json b/ui/web/public/locales/zh-Hans/common.json index 5530a84ee..3b9fa7639 100644 --- a/ui/web/public/locales/zh-Hans/common.json +++ b/ui/web/public/locales/zh-Hans/common.json @@ -18,6 +18,7 @@ "decline": "拒绝", "default": "默认", "delete": "删除", + "edit": "编辑", "empty": "暂无数据", "export": "导出", "export_succeed": "导出成功", @@ -38,6 +39,7 @@ "other": "其他", "position_long": "多", "position_short": "空", + "recover": "恢复", "reference_error": "引用错误: 无法于 {{importer}} 找到 {{source}},请检查工作区中是否存在该文件。", "report_bug": "报告缺陷", "reset": "重置", diff --git a/ui/web/src/modules/Deploy/ManifestList.tsx b/ui/web/src/modules/Deploy/ManifestList.tsx index 9fb4e9bdb..2d7ed2309 100644 --- a/ui/web/src/modules/Deploy/ManifestList.tsx +++ b/ui/web/src/modules/Deploy/ManifestList.tsx @@ -1,69 +1,115 @@ -import { Button, Space, Table } from '@douyinfe/semi-ui'; -import { registerPage } from '../Pages'; -import { supabase } from '../SupaBase'; -import { Subject, defer, repeat, shareReplay } from 'rxjs'; -import { useObservableState } from 'observable-hooks'; -import { IconDelete, IconRefresh } from '@douyinfe/semi-icons'; +import { IconDelete, IconRefresh, IconUndo } from '@douyinfe/semi-icons'; +import { Space, Table } from '@douyinfe/semi-ui'; +import { formatTime } from '@yuants/data-model'; +import { IDeploySpec } from '@yuants/extension'; import { t } from 'i18next'; +import { useObservableState } from 'observable-hooks'; +import { BehaviorSubject, Subject, defer, repeat, shareReplay } from 'rxjs'; import { executeCommand, registerCommand } from '../CommandCenter'; +import { Button } from '../Interactive'; +import { registerPage } from '../Pages'; +import { supabase } from '../SupaBase'; +import { useEffect } from 'react'; -const refreshAction$ = new Subject(); +export interface ISupabaseManifestRecord { + id: string; + user_id: string; + manifest: IDeploySpec; + created_at: string; + updated_at: string; + expired_at: string | null; +} -const shareManifests$ = defer(async () => { - const res = await supabase.from('manifest').select('*'); - const data: Array<{ - id: string; - content: {}; - deploy_key: string; - host_id: string; - }> = res.data || []; - return data; -}).pipe( - // +const ManifestList$ = new BehaviorSubject([]); - repeat({ delay: () => refreshAction$ }), - shareReplay(1), -); +registerCommand('Manifest.Load', async () => { + const res = await supabase.from('manifest').select('*'); + const data: Array = res.data || []; + ManifestList$.next(data); +}); registerCommand('Manifest.Delete', async ({ id }) => { - await supabase.from('manifest').delete().eq('id', id); - refreshAction$.next(); + await supabase + .from('manifest') + .update({ expired_at: formatTime(Date.now()) }) + .eq('id', id); + await executeCommand('Manifest.Load'); +}); + +registerCommand('Manifest.Recover', async ({ id }) => { + await supabase.from('manifest').update({ expired_at: null }).eq('id', id); + await executeCommand('Manifest.Load'); }); registerPage('ManifestList', () => { - const data = useObservableState(shareManifests$); + const data = useObservableState(ManifestList$); + + useEffect(() => { + executeCommand('Manifest.Load'); + }, []); return ( - + v.deploy_key, + title: 'ID', + render: (_, v) => v.id, + }, + { + title: 'Package', + render: (_, v) => v.manifest.package, + }, + { + title: 'Version', + render: (_, v) => v.manifest.version, + }, + { + title: 'Updated At', + render: (_, v) => formatTime(v.updated_at), + }, + { + title: 'Created At', + render: (_, v) => formatTime(v.created_at), + }, + { + title: 'Expired At', + render: (_, v) => (v.expired_at ? formatTime(v.expired_at) : '-'), + }, + { + title: 'Manifest', + width: 300, + render: (_, v) => JSON.stringify(v.manifest), }, { title: 'Actions', render: (_, v) => ( - + {/* */} + {v.expired_at && ( + + )} + {!v.expired_at && ( + + )} ), },